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.mzph.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…

企业转型必上的监控系统智能管家大屏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…

参数高效微调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…

2021 hnust 湖科大 数字系统设计与VHDL课程 大作业 - 出租车计价器设计

2021 hnust 湖科大 数字系统设计与VHDL课程大作业-出租车计价器设计 描述 大二上的eda考查课的实验&#xff0c;额外实现了停车等待2分钟后收费1元/min。内含项目文件&#xff08;实测可运行&#xff09;&#xff0c;代码&#xff0c;报告&#xff0c;视频和照片&#xff0c;…

功能强大且专业的PDF转换软件PDF Shaper Professional 14.2

PDF Shaper Professional是一款适用于Windows的程序&#xff0c;可让您在计算机上处理PDF文件。 要开始使用PDF Shaper Professional&#xff0c;您需要在Windows计算机上下载并安装该程序。您还应该有合适的驱动程序和编解码器来处理计算机上的文本和图形。 安装程序后&#…

分享一份糟糕透顶的简历,看看跟你写的一样不

最近看了一个人的简历&#xff0c;怎么说呢&#xff0c;前几年这么写没问题&#xff0c;投出去就有回复&#xff0c;但从现在开始&#xff0c;这么写肯定不行了。下面我给大家分享一下内容&#xff1a; 目录 &#x1f926;‍♀️这是简历文档截图 &#x1f937;‍♀️这是基本…

淘宝评论API调用指南,让你购物不再困扰

一、淘宝评论API概述 淘宝评论API是淘宝开放平台提供的一种服务&#xff0c;它允许开发者通过调用API接口获取淘宝商品评论数据&#xff0c;联讯数据从而为用户提供更加丰富和实用的购物决策信息。通过使用淘宝评论API&#xff0c;开发者可以轻松地实现以下功能&#xff1a; …

SwiftUI 利用 Swizz 黑魔法为系统创建的默认对象插入新协议方法(二)

功能需求 在 SwiftUI 的开发中,我们往往需要借助底层 UIKit 的“上帝之手”来进一步实现额外的定制功能。比如,在可拖放(Dragable)SwiftUI 的实现中,会缺失拖放取消的回调方法让我们这些秃头码农们“欲哭无泪” 如上图所示,我们在拖放取消时将界面中的一切改变都恢复如初…