当前位置: 首页 > news >正文

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();}
}
MFCGridView使用方法:xml中直接引用即可,无需其他操作

---------------------------------------------------------分割线---------------------------------------------------------

依赖类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();}} 
}

MFCListView实际使用例子:

1.xml代码中使用MFCListView类代替

2.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父控件也跟着下滑了!!!

相关文章:

MFC实现子控件focus焦点上下移动父控件ListView和Gridview也跟着向上下移动

项目中要实现mfc功能&#xff0c;然后子控件焦点下移&#xff0c;LIstView和Gridview父控件不会下移&#xff0c;所以就有这个文章。废话不多说直接上代码。 MFCGridView.java import android.content.Context; import android.util.AttributeSet; import android.view.View;…...

几何关系运算处理

1. 判断点在线的左边还是右边 要判断一个坐标点在直线的左侧还是右侧&#xff0c;可以使用向量叉积。具体来说&#xff0c;对于给定的直线和点&#xff0c;我们可以计算点到直线的向量与直线的方向向量的叉积。叉积的符号可以用于判断点的位置关系&#xff1a; 如果叉积为正&…...

http和https分别是什么?区别是什么?

HTTP和HTTPS是两种常见的网络协议&#xff0c;用于在Web上进行数据传输。以下是它们的简要解释和主要区别&#xff1a; HTTP&#xff08;Hypertext Transfer Protocol&#xff09; HTTP是一种应用层协议&#xff0c;用于在Web上传输数据。它是互联网上应用最为广泛的一种网络…...

第一周:计算机网络概述(上)

一、计算机网络基本概念 1、计算机网络通信技术计算机技术 计算机网络就是一种特殊的通信网络&#xff0c;其特殊之处就在于它的信源和信宿就是计算机。 2、什么是计算机网络 在计算机网络中&#xff0c;我们把这些计算机统称为“主机”&#xff08;上图中所有相连的电脑和服…...

谷歌AI搜索变革,中国引擎能跟上步伐?

全文预计1200字左右&#xff0c;预计阅读需要6分钟。 一年前&#xff0c;谷歌宣布人工智能将引领搜索的未来&#xff0c;如今&#xff0c;这一愿景正逐步实现。谷歌已在美国推出并即将全球推广"AI Overviews"&#xff0c;为用户提供由AI生成的搜索结果概览&#xff0…...

【机器学习300问】110、什么是Lasso回归模型?

LASSO回归的全称是Least Absolute Shrinkage and Selection Operator&#xff0c;中文叫“最小绝对收缩和选择算子”&#xff0c;用一个比喻来初步感受一下它的作用&#xff1a; 想象你在整理一个杂乱无章的房间&#xff0c;里面堆满了各种物品&#xff08;代表众多的预测变量&…...

Qt实现麦克风音频输入保存wav文件

一.本文目的 实现在Qt中接收麦克风数据并保存为WAV文件&#xff0c;使用QAudioInput来录音&#xff0c;并使用QFile来保存数据到WAV文件。 开发环境&#xff1a;QT5.12 本文用极简代码实现&#xff0c;核心代码只需不到100行。 完整工程代码文末链接可以直接下载。 二.代码实…...

docker_如何推送镜像到仓库(hub.docker.com)

在执行 docker push 时收到 denied: requested access to the resource is denied 错误通常意味着你没有权限将镜像推送到目标存储库。这可能有几个原因,包括: 未登录 Docker Hub:你还没有登录到 Docker Hub,或者你登录的账户没有权限推送到目标存储库。存储库不存在:目标…...

【Python】认识 Python

一、计算机基础概念 1、什么是计算机 很多老一辈的人&#xff0c;管下面这个叫做计算机。然而&#xff0c;它只是 “计算器”&#xff0c;和计算机是有很大区别的。 现在我们所说的计算机&#xff0c;不光能进行算术运算&#xff0c;还能进行逻辑判断、数据存储、网络通信等…...

Vue根据后端返回的tabList动态渲染组件信息

最近做了一个功能&#xff0c;后端根据配置信息&#xff0c;动态返回一个tabList&#xff0c;其中结构是List<String,Object> tabList; map里面的数据是 label、value 页面需要根据tablist动态渲染组件&#xff08;不同的tab都使用了组件进行了封装&#xff09; 实现效果…...

二轴机器人大米装箱机:技术创新引领智能包装新潮流

在科技日新月异的今天&#xff0c;自动化和智能化已成为各行各业追求高效、精准生产的关键。作为粮食加工行业的重要一环&#xff0c;大米装箱机的技术创新与应用价值日益凸显。其中&#xff0c;二轴机器人大米装箱机以其高效、稳定、智能的特点&#xff0c;成为市场的新宠。星…...

rtl8723DU移植 android4.4 4418 (第二部分蓝牙部分)

使用的代码&#xff1a; HMI &#xff08;8723bu&#xff09;源码 567_RTL8723DU_WiFi_linux_v5.6.5.3_35502_COEX20181130-2e2e.20191025.zip 由于之前写的所有笔记没有保存&#xff0c;这里只能是部分。 0、 前置知识 1 、kernel 的移植 2、hardwire的移植 将 驱动中的 h…...

【Vue】组件的存放目录问题

注意&#xff1a; .vue文件 本质无区别 组件分类 .vue文件分为2类&#xff0c;都是 .vue文件&#xff08;本质无区别&#xff09; 页面组件 &#xff08;配置路由规则时使用的组件&#xff09;复用组件&#xff08;多个组件中都使用到的组件&#xff09; 存放目录 分类开来的…...

开发PlugLink插件:自动生成并发布博客文章

开发PlugLink插件&#xff1a;自动生成并发布博客文章 引言 博客已经成为个人和企业分享信息、推广产品的重要工具。然而&#xff0c;手动运营博客不仅耗时&#xff0c;而且容易出错。本文将介绍如何利用PlugLink开发一个全自动博客运营程序&#xff0c;通过API链接大模型&am…...

Ant Design Pro

一&#xff1a;Ant Design pro是什么&#xff1a; Ant Design Pro 是基于 Ant Design 和 umi 的封装的一整套企业级中后台前端/设计解决方案&#xff0c;致力于在设计规范和基础组件的基础上&#xff0c;继续向上构建&#xff0c;提炼出典型模板/业务组件/配套设计资源&#x…...

加密软件好用的是哪个?为什么这么多人说迅软DSE加密软件好用?

加密软件顾名思义就是用来对机密文件进行加密保护的&#xff0c;防止未经授权的人查看和篡改&#xff0c;保护公司的重要信息&#xff0c;预防泄露的事件发生&#xff0c;由此可见运用加密软件是有用的。那么&#xff0c;问题又来了哪款加密软件好呢&#xff1f;请看一下介绍。…...

大模型日报2024-06-07

大模型日报 2024-06-07 大模型资讯 大规模单细胞转录组学基础模型研究 摘要: 大型预训练模型已成为基础模型&#xff0c;在自然语言处理及相关领域取得突破。本文介绍了在单细胞转录组学领域应用大规模基础模型的研究进展。 MMLU-Pro&#xff1a;评估语言理解模型的新基准 摘要…...

Day49 动态规划part08

LC139单词拆分(未掌握) 未掌握分析&#xff1a;将字符串s中的各个字符看成是背包&#xff0c;思考成了多重背包问题单词就是物品&#xff0c;字符串s就是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满。拆分时可以重复使用字典中的单词&#xf…...

React -- memo允许你的组件在 props 没有改变的情况下跳过重新渲染。

memo(Component, arePropsEqual?) 使用 memo 将组件包装起来&#xff0c;以获得该组件的一个 记忆化 版本。通常情况下&#xff0c;只要该组件的 props 没有改变&#xff0c;这个记忆化版本就不会在其父组件重新渲染时重新渲染。但 React 仍可能会重新渲染它&#xff1a;记忆化…...

路径

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 用于定位一个文件或者目录的字符串被称为一个路径。在程序开发时&#xff0c;通常涉及两种路径&#xff0c;一种是相对路径&#xff0c;另一种是绝对…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...