MFC實現子控件focus焦點上下移動父控件ListView和Gridview也跟著向上下移動

項目中要實現mfc功能,然后子空間焦點下移,LIstView和Gridview父空間不會下移,所以就有這個文章。廢話不多說直接上代碼。

MFCGridView.java

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.GridView;import com.baidu.navisdk.ui.util.MFCUtil;public class MFCGridView extends GridView {protected int lastPosition = -1;protected boolean mHasRegister = false;private final ViewTreeObserver.OnGlobalFocusChangeListener mFocusChangeListener =new ViewTreeObserver.OnGlobalFocusChangeListener() {@Overridepublic void onGlobalFocusChanged(View oldFocus, View newFocus) {if (!isInTouchMode()) {refreshListViewScroll(oldFocus, newFocus);}}};protected void refreshListViewScroll(View oldFocus, View newFocus) {if (getVisibility() != VISIBLE) {return;}if (newFocus == null) {return;}ViewParent convertView = getConvertView(newFocus);if (convertView == null) {return;}if (!(convertView instanceof View)) {return;}Object tagView = ((View) convertView).getTag();if (!(tagView instanceof IMFCHolder)) {if (lastPosition!= getAdapter().getCount() - 1) {smoothScrollToPositionFromTop(0, 0);lastPosition = -1;}return;}int focusedPosition = -1;View focusedChild =  getFocusedChild();if (focusedChild != null) {focusedPosition =  getPositionForView(focusedChild);}if (focusedPosition != lastPosition) {smoothScrollToPositionFromTop(focusedPosition, 50);lastPosition = focusedPosition;}}protected ViewParent getConvertView(View newFocus) {ViewParent lastView = null;ViewParent parent = newFocus.getParent();if (parent == this){return (ViewParent) newFocus;}while (parent != null) {if (parent == this) {return lastView;}lastView = parent;parent = parent.getParent();}return null;}public MFCGridView(Context context) {super(context);setFocusableInTouchMode(false);}public MFCGridView(Context context, AttributeSet attrs) {super(context, attrs);setFocusableInTouchMode(false);}public MFCGridView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);setFocusableInTouchMode(false);}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();if (MFCUtil.isMFCEnable()) {if (!mHasRegister) {getViewTreeObserver().addOnGlobalFocusChangeListener(mFocusChangeListener);mHasRegister = true;}}}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();if (MFCUtil.isMFCEnable()) {getViewTreeObserver().removeOnGlobalFocusChangeListener(mFocusChangeListener);mHasRegister = false;}clearDisappearingChildren();}
}
依賴類IMFCHolder.java
public interface IMFCHolder {int getPosition();
}

MFCListView.java

 import com.baidu.navisdk.ui.util.MFCUtil;import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.ListView;public class MFCListView extends ListView {protected boolean mHasRegister = false;protected int lastPosition = -1;private final ViewTreeObserver.OnGlobalFocusChangeListener mFocusChangeListener =new ViewTreeObserver.OnGlobalFocusChangeListener() {@Overridepublic void onGlobalFocusChanged(View oldFocus, View newFocus) {if (!isInTouchMode()) {refreshListViewScroll(oldFocus, newFocus);}}};protected void refreshListViewScroll(View oldFocus, View newFocus) {if (getVisibility() != VISIBLE) {return;}if (newFocus == null) {return;}ViewParent convertView = getConvertView(newFocus);if (convertView == null) {return;}if (!(convertView instanceof View)) {return;}Object tagView = ((View) convertView).getTag();if (!(tagView instanceof IMFCHolder)) {if (lastPosition!= getAdapter().getCount() - getHeaderViewsCount() - getFooterViewsCount()- 1) {smoothScrollToPositionFromTop(0, 0);lastPosition = -1;}return;}IMFCHolder imfcHolder = (IMFCHolder) tagView;int position = imfcHolder.getPosition();if (position != lastPosition) {smoothScrollToPositionFromTop(position + getHeaderViewsCount(), 50);lastPosition = position;}}protected ViewParent getConvertView(View newFocus) {ViewParent lastView = null;ViewParent parent = newFocus.getParent();if (parent == this){return (ViewParent) newFocus;}while (parent != null) {if (parent == this) {return lastView;}lastView = parent;parent = parent.getParent();}return null;}public MFCListView(Context context) {super(context);setFocusableInTouchMode(false);}public MFCListView(Context context, AttributeSet attrs) {super(context, attrs);setFocusableInTouchMode(false);}public MFCListView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);setFocusableInTouchMode(false);}public MFCListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);setFocusableInTouchMode(false);}@Overridepublic View getFocusedChild() {return null;}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();if (MFCUtil.isMFCEnable()) {if (!mHasRegister) {getViewTreeObserver().addOnGlobalFocusChangeListener(mFocusChangeListener);mHasRegister = true;}}}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();if (MFCUtil.isMFCEnable()) {getViewTreeObserver().removeOnGlobalFocusChangeListener(mFocusChangeListener);mHasRegister = false;}clearDisappearingChildren();}
}

依賴類MFCUtil.java

package com.baidu.navisdk.ui.util;import android.app.Activity;import com.baidu.naviauto.appcommon.AppLog;import java.util.ArrayList;
import java.util.List;public class MFCUtil {private static final String TAG = "MFCUtil";public static final List<String> REQUEST_CHECK_LIST_STRING = new ArrayList<>();public static boolean isMFCEnable() {return true;}/***  返回false 不消費 調用者可以request*  返回true   消費  調用者不可以request* @param activity* @param classname* @return*/public static boolean requestCheck(Activity activity, String classname) {if (activity == null) {return true;}if (!isMFCEnable()) {return true;}if (activity.getWindow().getDecorView().isInTouchMode()){return true;}checkRequestCheckList(activity);if (REQUEST_CHECK_LIST_STRING == null) {AppLog.e(TAG, "checkRequestCheckList  ==  " + classname);return false;}for (int i = 0; i < REQUEST_CHECK_LIST_STRING.size(); i++) {if (REQUEST_CHECK_LIST_STRING.get(i).equals(classname)) {AppLog.e(TAG, "false  ==  " + classname);return false;}}AppLog.e(TAG, "false finish  ==  " + classname);return false;}public static void checkRequestCheckList(Activity activity) {if (REQUEST_CHECK_LIST_STRING != null && REQUEST_CHECK_LIST_STRING.size() == 0) {REQUEST_CHECK_LIST_STRING.add("PowerNotification");REQUEST_CHECK_LIST_STRING.add("RestrictionTipsView");REQUEST_CHECK_LIST_STRING.add("RecommendTripTipsView");REQUEST_CHECK_LIST_STRING.add("PushPoiNaviNotificationView");REQUEST_CHECK_LIST_STRING.add("PushPoiNaviNotificationDialog");REQUEST_CHECK_LIST_STRING.add("NaviAutoActivity");}}public static void onDestory(){if (REQUEST_CHECK_LIST_STRING != null){REQUEST_CHECK_LIST_STRING.clear();}} 
}

實際使用例子:

adapter中,核心代碼如下:

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.item_column, null);viewHolder = new ViewHolder();viewHolder.textView = convertView.findViewById(R.id.text);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.position = position;viewHolder.textView.setText(mProvinShotNameArr[position]);return convertView;}public static class ViewHolder  implements IMFCHolder {TextView textView;int position;@Overridepublic int getPosition() {return position;}}

實現成功:子控件焦點滑到中間,gridview父控件也跟著下滑了!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/22268.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/22268.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/22268.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

白酒:產地的釀酒歷史與文化遺產

云倉酒莊豪邁白酒作為中國釀酒工藝的品牌之一&#xff0c;其產地的釀酒歷史與文化遺產具有深遠的意義和價值。產地釀酒歷史悠久&#xff0c;代代相傳的釀酒技藝和與眾不同的文化傳統&#xff0c;構成了云倉酒莊豪邁白酒與眾不同的品質和風味。 據云倉酒莊豪邁介紹&#xff0c;中…

力扣----輪轉數組

題目鏈接&#xff1a;189. 輪轉數組 - 力扣&#xff08;LeetCode&#xff09; 思路一 我們可以在進行每次輪轉的時候&#xff0c;先將數組的最后一個數據的值存儲起來&#xff0c;接著將數組中前n-1個數據依次向后移&#xff0c;最后將存儲起來的值賦給數組中的第一個數據。 …

Pixi繪制地圖和小車

之前已經用Pixi繪制出了各種圖形以及通過圖片繪制精靈&#xff0c;這節用pixi繪制網格地圖&#xff0c;并通過圖片制作一個Sprite&#xff0c;讓這個Sprite在網格地圖上運動。首先需要在頁面中添加一個div用來后期展示canvas的畫布&#xff0c;并將此div實例化為PIXI的Applicat…

python繪制雙變量熱力等級圖

參考資料&#xff1a; https://github.com/mikhailsirenko/bivariate-choropleth/blob/main/bivariate-choropleth.ipynb Bivariate choropleth map using Plotly Matplotlib雙變量熱力等級圖 代碼&#xff1a; import pandas as pd import geopandas as gpd import numpy a…

企業轉型必上的監控系統智能管家大屏UI前端開發

企業轉型必上的監控系統智能管家大屏UI前端開發

Istio安裝記錄

環境介紹 我使用的是k8s 1.23.3版本 istio使用的是istio-1.13.3-linux-amd64.tar.gz 把文件下載k8s集群下&#xff0c;解壓 tar -vzxf istio-1.13.3-linux-amd64.tar.gz然后設置環境變量 [rootmaster istio]# cat /etc/profile export ISTIO_HOME/root/istio-1.13.3 expor…

3067. 在帶權樹網絡中統計可連接服務器對數目 Medium

給你一棵無根帶權樹&#xff0c;樹中總共有 n 個節點&#xff0c;分別表示 n 個服務器&#xff0c;服務器從 0 到 n - 1 編號。同時給你一個數組 edges &#xff0c;其中 edges[i] [ai, bi, weighti] 表示節點 ai 和 bi 之間有一條雙向邊&#xff0c;邊的權值為 weighti 。再給…

Yolo-v5模型訓練速度,與GeForce的AI算力描述

1.GeForce RTX3070 Ti官網參數&#xff1a; GeForce RTXTM 3070 Ti 和 RTX 3070 顯卡采用第 2 代 NVIDIA RTX 架構 - NVIDIA Ampere 架構。該系列產品搭載專用的第 2 代 RT Core &#xff0c;第 3 代 Tensor Core、全新的 SM 多單元流處理器以及高速顯存&#xff0c;助您在高性…

【網絡安全的神秘世界】MySQL

&#x1f31d;博客主頁&#xff1a;泥菩薩 &#x1f496;專欄&#xff1a;Linux探索之旅 | 網絡安全的神秘世界 | 專接本 MySQL MySQL 教程 | 菜鳥教程 (runoob.com) 什么是數據庫 數據庫&#xff08;Database&#xff09;是按照數據結構來組織、存儲和管理數據的倉庫 在do…

二手筆記本怎么買

用途&#xff1a; 1.給爹媽用來簡單辦公&#xff0c;只是用office基礎辦公軟件&#xff0c;無出差無游戲無畫圖需求。 預算&#xff1a; 1000以內 以下是電腦對比選項&#xff1a; 屏幕大小-> 目前市面上的尺寸對比&#xff0c;以A4紙說明&#xff0c;13.3寸14.1寸15.6…

Camunda 7.x 系列【66】實戰篇之我發起的

有道無術,術尚可求,有術無道,止于術。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源碼地址:https://gitee.com/pearl-organization/camunda-study-demo 前后端基于若依:https://gitee.com/y_project/RuoYi-Vue 流程設計器基于RuoYi-flowable:https://gi…

參數高效微調PEFT(四)快速入門(IA)3

參數高效微調PEFT(四)快速入門(IA)3 我們已經了解了HuggingFace中peft庫的幾種高效微調方法。 參數高效微調PEFT(一)快速入門BitFit、Prompt Tuning、Prefix Tuning 參數高效微調PEFT(二)快速入門P-Tuning、P-Tuning V2 參數高效微調PEFT(三)快速入門LoRA、AdaLoRA 今天我…

探索 Omost:創新的圖像生成AI框架

文章目錄 探索 Omost&#xff1a;創新的圖像生成AI框架第一部分&#xff1a;背景第二部分&#xff1a;Omost是什么&#xff1f;第三部分&#xff1a;如何安裝Omost&#xff1f;第四部分&#xff1a;結合具體場景使用第五部分&#xff1a;總結 探索 Omost&#xff1a;創新的圖像…

OceanBase 4.3 特性解析:列存技術

在涉及大規模數據的復雜分析或即時查詢時&#xff0c;列式存儲是支撐業務負載的關鍵技術之一。相較于傳統的行式存儲&#xff0c;列式存儲采用了不同的數據文件組織方式&#xff0c;它將表中的數據以列為單位進行物理排列。這種存儲模式允許在分析過程中&#xff0c;查詢計算僅…

flowable工作流 完成任務代碼 及擴展節點審核人(實現多級部門主管 審核等)詳解【JAVA+springboot】

低代碼項目 使用flowable 工作流 完成任務代碼 詳解 可以看到 complete()方法 傳遞了流程變量參數var 前端傳遞此參數就可以實現 流程中 審批 更新流程變量參數var 也可以進行更多擴展 實現流程中更新表單內容功能 啟動流程實例代碼 實現對于流程自定義 動態節點審核人 功…

中央空調節能的分戶計費系統

中央空調節能 在建筑能耗中&#xff0c;中央空調能耗一般占到了40%---60%的比例&#xff0c;因此如何有效降低空調能耗就成為建筑節能的重中之重。 項目案例描述 山東銀座購物廣場&#xff1a;為集購物中心、高級酒店式公寓和辦公為一體的綜合性公共建筑。整體建筑共為地下3層&…

副業變現:Midjourney繪畫賺錢的6種方式

今年被稱為AI元年&#xff0c;其中最火的兩款AI工具非ChatGpt和Midjourney莫屬。究其原因&#xff0c;無非兩點&#xff1a;第一&#xff0c;它提高了生產力&#xff0c;之前需要兩年完成的工作&#xff0c;使用ChatGpt兩天就完成。 第二&#xff0c;它帶來了副業收入&#x…

JavaScript異步編程簡單介紹

JavaScript異步編程是一種編程模式&#xff0c;用于處理需要等待某些操作完成之后才能繼續執行的代碼。這些操作可以是網絡請求、文件讀取、定時器等等。 異步編程的目標是避免阻塞代碼執行&#xff0c;在等待操作完成的同時&#xff0c;允許其他代碼繼續執行。 以下是一個使…

Springboot-RabbitMQ 消息隊列使用

一、概念介紹&#xff1a; RabbitMQ中幾個重要的概念介紹&#xff1a; Channels&#xff1a;信道&#xff0c;多路復用連接中的一條獨立的雙向數據流通道。信道是建立在真實的 TCP 連接內地虛擬連接&#xff0c;AMQP 命令都是通過信道發出去的&#xff0c;不管是發布消息、訂閱…

2021 hnust 湖科大 數字系統設計與VHDL課程 大作業 - 出租車計價器設計

2021 hnust 湖科大 數字系統設計與VHDL課程大作業-出租車計價器設計 描述 大二上的eda考查課的實驗&#xff0c;額外實現了停車等待2分鐘后收費1元/min。內含項目文件&#xff08;實測可運行&#xff09;&#xff0c;代碼&#xff0c;報告&#xff0c;視頻和照片&#xff0c;…