android多级树形列表-程序员宅基地

技术标签: 程序员  android  

import java.util.List;

import android.content.Context;

import android.view.View;

import android.view.ViewGroup;

import android.widget.CheckBox;

import android.widget.CompoundButton;

import android.widget.CompoundButton.OnCheckedChangeListener;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.TextView;

import com.example.customtreeviewdemo.tree.Node;

import com.example.customtreeviewdemo.tree.TreeListViewAdapter;

public class MyTreeListViewAdapter extends TreeListViewAdapter {

public MyTreeListViewAdapter(ListView mTree, Context context,

List datas, int defaultExpandLevel,boolean isHide)

throws IllegalArgumentException, IllegalAccessException {

super(mTree, context, datas, defaultExpandLevel,isHide);

}

@SuppressWarnings(“unchecked”)

@Override

public View getConvertView(Node node, int position, View convertView,

ViewGroup parent) {

ViewHolder viewHolder = null;

if (convertView == null)

{

convertView = mInflater.inflate(R.layout.list_item, parent, false);

viewHolder = new ViewHolder();

viewHolder.icon = (ImageView) convertView

.findViewById(R.id.id_treenode_icon);

viewHolder.label = (TextView) convertView

.findViewById(R.id.id_treenode_name);

viewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.id_treeNode_check);

convertView.setTag(viewHolder);

} else

{

viewHolder = (ViewHolder) convertView.getTag();

}

if (node.getIcon() == -1)

{

viewHolder.icon.setVisibility(View.INVISIBLE);

} else

{

viewHolder.icon.setVisibility(View.VISIBLE);

viewHolder.icon.setImageResource(node.getIcon());

}

if(node.isHideChecked()){

viewHolder.checkBox.setVisibility(View.GONE);

}else{

viewHolder.checkBox.setVisibility(View.VISIBLE);

setCheckBoxBg(viewHolder.checkBox,node.isChecked());

}

viewHolder.label.setText(node.getName());

return convertView;

}

private final class ViewHolder

{

ImageView icon;

TextView label;

CheckBox checkBox;

}

/**

  • checkbox是否显示

  • @param cb

  • @param isChecked

*/

private void setCheckBoxBg(CheckBox cb,boolean isChecked){

if(isChecked){

cb.setBackgroundResource(R.drawable.check_box_bg_check);

}else{

cb.setBackgroundResource(R.drawable.check_box_bg);

}

}

}

自定义TreeListViewAdapter  这个是整个树形结构的一个适配器,这里面主要是实现对Node节点的操作 点击,选中改变 更新等

package com.example.customtreeviewdemo.tree;

import java.util.ArrayList;

import java.util.List;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.BaseAdapter;

import android.widget.CheckBox;

import android.widget.CompoundButton;

import android.widget.CompoundButton.OnCheckedChangeListener;

import android.widget.ListView;

import android.widget.RelativeLayout;

/**

  • tree适配器

  • @param

*/

public abstract class TreeListViewAdapter extends BaseAdapter {

protected Context mContext;

/**

  • 存储所有可见的Node

*/

protected List mNodes;

protected LayoutInflater mInflater;

/**

  • 存储所有的Node

*/

protected List mAllNodes;

/**

  • 点击的回调接口

*/

private OnTreeNodeClickListener onTreeNodeClickListener;

public interface OnTreeNodeClickListener {

/**

  • 处理node click事件

  • @param node

  • @param position

*/

void onClick(Node node, int position);

/**

  • 处理checkbox选择改变事件

  • @param node

  • @param position

  • @param checkedNodes

*/

void onCheckChange(Node node, int position,List checkedNodes);

}

public void setOnTreeNodeClickListener(

OnTreeNodeClickListener onTreeNodeClickListener) {

this.onTreeNodeClickListener = onTreeNodeClickListener;

}

/**

  • @param mTree

  • @param context

  • @param datas

  • @param defaultExpandLevel

  •        默认展开几级树
    
  • @throws IllegalArgumentException

  • @throws IllegalAccessException

*/

public TreeListViewAdapter(ListView mTree, Context context, List datas,

int defaultExpandLevel, boolean isHide)

throws IllegalArgumentException, IllegalAccessException {

mContext = context;

/**

  • 对所有的Node进行排序

*/

mAllNodes = TreeHelper

.getSortedNodes(datas, defaultExpandLevel, isHide);

/**

  • 过滤出可见的Node

*/

mNodes = TreeHelper.filterVisibleNode(mAllNodes);

mInflater = LayoutInflater.from(context);

/**

  • 设置节点点击时,可以展开以及关闭;并且将ItemClick事件继续往外公布

*/

mTree.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view,

int position, long id) {

expandOrCollapse(position);

if (onTreeNodeClickListener != null) {

onTreeNodeClickListener.onClick(mNodes.get(position),

position);

}

}

});

}

/**

  • 相应ListView的点击事件 展开或关闭某节点

  • @param position

*/

public void expandOrCollapse(int position) {

Node n = mNodes.get(position);

if (n != null)// 排除传入参数错误异常

{

if (!n.isLeaf()) {

n.setExpand(!n.isExpand());

mNodes = TreeHelper.filterVisibleNode(mAllNodes);

notifyDataSetChanged();// 刷新视图

}

}

}

@Override

public int getCount() {

return mNodes.size();

}

@Override

public Object getItem(int position) {

return mNodes.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

final Node node = mNodes.get(position);

convertView = getConvertView(node, position, convertView, parent);

// 设置内边距

convertView.setPadding(node.getLevel() * 30, 3, 3, 3);

if (!node.isHideChecked()) {

//获取各个节点所在的父布局

RelativeLayout myView = (RelativeLayout) convertView;

//父布局下的CheckBox

CheckBox cb = (CheckBox) myView.getChildAt(1);

cb.setOnCheckedChangeListener(new OnCheckedChangeListener(){

@Override

public void onCheckedChanged(CompoundButton buttonView,

boolean isChecked) {

TreeHelper.setNodeChecked(node, isChecked);

List checkedNodes = new ArrayList();

for(Node n:mAllNodes){

if(n.isChecked()){

checkedNodes.add(n);

}

}

onTreeNodeClickListener.onCheckChange(node,position,checkedNodes);

TreeListViewAdapter.this.notifyDataSetChanged();

}

});

}

return convertView;

}

public abstract View getConvertView(Node node, int position,

View convertView, ViewGroup parent);

/**

  • 更新

  • @param isHide

*/

public void updateView(boolean isHide){

for(Node node:mAllNodes){

node.setHideChecked(isHide);

}

this.notifyDataSetChanged();

}

}

node 模型类

package com.example.customtreeviewdemo.bean;

public class MyNodeBean {

/**

  • 节点Id

*/

private int id;

/**

  • 节点父id

*/

private int pId;

/**

  • 节点name

*/

private String name;

/**

*/

private String desc;

/**

  • 节点名字长度

*/

private long length;

public MyNodeBean(int id, int pId, String name) {

super();

this.id = id;

this.pId = pId;

this.name = name;

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public int getPid() {

return pId;

}

public void setPid(int pId) {

this.pId = pId;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getDesc() {

return desc;

}

public void setDesc(String desc) {

this.desc = desc;

}

public long getLength() {

return length;

}

public void setLength(long length) {

this.length = length;

}

}

TreeHelper这个也是核心操作类,主要功能是将业务数据和节点数据进行匹配

package com.example.customtreeviewdemo.tree;

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.List;

import com.example.customtreeviewdemo.R;

public class TreeHelper {

/**

  • 根据所有节点获取可见节点

  • @param allNodes

  • @return

*/

public static List filterVisibleNode(List allNodes) {

List visibleNodes = new ArrayList();

for (Node node : allNodes) {

// 如果为根节点,或者上层目录为展开状态

if (node.isRoot() || node.isParentExpand()) {

setNodeIcon(node);

visibleNodes.add(node);

}

}

return visibleNodes;

}

/**

  • 获取排序的所有节点

  • @param datas

  • @param defaultExpandLevel

  • @return

  • @throws IllegalArgumentException

  • @throws IllegalAccessException

*/

public static List getSortedNodes(List datas,

int defaultExpandLevel, boolean isHide)

throws IllegalAccessException, IllegalArgumentException {

List sortedNodes = new ArrayList();

// 将用户数据转化为List

List nodes = convertData2Nodes(datas, isHide);

// 拿到根节点

List rootNodes = getRootNodes(nodes);

// 排序以及设置Node间关系

for (Node node : rootNodes) {

addNode(sortedNodes, node, defaultExpandLevel, 1);

}

return sortedNodes;

}

/**

  • 把一个节点上的所有的内容都挂上去

*/

private static void addNode(List nodes, Node node,

int defaultExpandLeval, int currentLevel) {

nodes.add(node);

if (defaultExpandLeval >= currentLevel) {

node.setExpand(true);

}

if (node.isLeaf())

return;

for (int i = 0; i < node.getChildrenNodes().size(); i++) {

addNode(nodes, node.getChildrenNodes().get(i), defaultExpandLeval,

currentLevel + 1);

}

}

/**

  • 获取所有的根节点

  • @param nodes

  • @return

*/

public static List getRootNodes(List nodes) {

List rootNodes = new ArrayList();

for (Node node : nodes) {

if (node.isRoot()) {

rootNodes.add(node);

}

}

return rootNodes;

}

/**

  • 将泛型datas转换为node

  • @param datas

  • @return

  • @throws IllegalArgumentException

  • @throws IllegalAccessException

*/

public static List convertData2Nodes(List datas, boolean isHide)

throws IllegalAccessException, IllegalArgumentException {

List nodes = new ArrayList();

Node node = null;

for (T t : datas) {

int id = -1;

int pId = -1;

String name = null;

Class<? extends Object> clazz = t.getClass();

Field[] declaredFields = clazz.getDeclaredFields();

/**

  • 与MyNodeBean实体一一对应

*/

for (Field f : declaredFields) {

if (“id”.equals(f.getName())) {

f.setAccessible(true);

id = f.getInt(t);

}

if (“pId”.equals(f.getName())) {

f.setAccessible(true);

pId = f.getInt(t);

}

if (“name”.equals(f.getName())) {

f.setAccessible(true);

name = (String) f.get(t);

}

if (“desc”.equals(f.getName())) {

continue;

}

if (“length”.equals(f.getName())) {

continue;

}

if (id == -1 && pId == -1 && name == null) {

break;

}

}

node = new Node(id, pId, name);

node.setHideChecked(isHide);

nodes.add(node);

}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

尾声

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。

  • 思维脑图
  • 性能优化学习笔记


  • 性能优化视频

    当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

…(img-XpRa8f8A-1713839080253)]

[外链图片转存中…(img-2umZwy9w-1713839080254)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

[外链图片转存中…(img-hxdOdLvn-1713839080256)]

尾声

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

最后想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。

  • 思维脑图
    [外链图片转存中…(img-e9rTBGJX-1713839080257)]
  • 性能优化学习笔记
    [外链图片转存中…(img-WaWNFb8g-1713839080258)]
    [外链图片转存中…(img-cqR2uQQ7-1713839080259)]

[外链图片转存中…(img-gW3VCfpt-1713839080260)]
[外链图片转存中…(img-VdM6drqq-1713839080261)]

  • 性能优化视频
    [外链图片转存中…(img-stwrXPpI-1713839080262)]
    当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/2401_84132401/article/details/138114607

智能推荐

日期与时间处理详解_0\洲-程序员宅基地

文章浏览阅读1.2k次,点赞7次,收藏2次。时间相关概念秒在1967年的第13届国际度量衡会议上决定以原子时定义的秒作为时间的国际标准单位:铯133原子基态的两个超精细能阶间跃迁对应辐射的9,192,631,770个周期的持续时间, 起始历元定在1958年1月1日0时。原子钟是一种时钟,它以原子共振频率标准来计算及保持时间的准确。原子钟是世界上已知最准确的时间测量和频率标准。GMT格林威治标准时间(Greenwich Mean Time),是指位于伦敦郊区的皇家格林威治天文台的标准时间,因为本初子午线(Prime merid..._0\洲

java 的 io流 读取文件里面 的内容(不定时更新)_java io读取文件内容-程序员宅基地

文章浏览阅读4.8k次,点赞4次,收藏29次。io流_java io读取文件内容

图像处理——过程全解析,配图超详细!-程序员宅基地

文章浏览阅读1.4k次。点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达摘自先进测控之家《长着眼睛的机械手》课题摘要——利用图像处理技术,在50*50CM的区域内识别出5枚硬币(硬币位置任意),并且控制机械手逐一拾取5枚硬币,然后把5枚硬币逐一叠放到指定位置(指定位置随机)。图像处理过程详解——LabVIEWVision Assistant硬币位置识别算法分析与设计硬币的识别是本系统软件设计最为关..._图像处理

[ MATLAB ] 傅里叶变换(三):傅里叶变换_傅里叶变换可视化,plot3函数,matlab-程序员宅基地

文章浏览阅读774次,点赞35次,收藏25次。专题的前两篇文章([ MATLAB ] 傅里叶变换(二):傅里叶级数(复指数表示)),我们讨论了连续周期信号傅里叶级数的两种表示形式,初步建立了频谱的概念。然而,就实际经验而言,非周期信号才是主流。因此,这篇文章将讨论非周期连续信号的谱密度(通常简称为频谱),即大名鼎鼎的傅里叶变换FT,并用Matlab仿真加强理解。可以采用物理中的密度的方式类比谱密度的概念,从而理解傅里叶变换中谱密度的意义。不需要再执着于分量幅值的绝对大小,而是聚焦于相对大小。_傅里叶变换可视化,plot3函数,matlab

5G手机回归,鸿蒙份额激增,将进一步夯实三大操作系统的地位-程序员宅基地

文章浏览阅读360次,点赞8次,收藏8次。市调机构给出的数据指11月份华为手机在国内手机市场的份额达到14%,远超此前鸿蒙系统在国内手机操作系统8%的市场份额,这意味着随着华为5G手机的回归,鸿蒙系统的市占率将快速上涨。此前鸿蒙系统主要依靠华为手机的存量用户支持,在华为的推动下,诸多华为存量手机用户都转为了鸿蒙系统,这成为鸿蒙系统的第一批种子。随后华为在自己的穿戴设备、汽车等诸多产品上发展鸿蒙系统,还通过与美的等国内家电企业合作推广鸿蒙系...

openstack pike单机一键安装shell的方法(后期会转为python)-程序员宅基地

文章浏览阅读183次,点赞9次,收藏2次。#VM虚拟机8G内存,安装完毕,半个小时左右#在线安装#环境 centos 7.4.1708 x86_64#在线安装openstack pikePS: 排版问题,还在研究。wangleideMacBook-Pro:Downloads wanglei$ cat pike.install.sh#!/bin/sh# openstack pike 单机 一键安装# 环..._ali-pike.repo

随便推点

ceph中的radosgw相关总结_radosgw -c-程序员宅基地

文章浏览阅读627次。https://blog.csdn.net/zrs19800702/article/details/53101213http://blog.csdn.net/lzw06061139/article/details/51445311https://my.oschina.net/linuxhunter/blog/654080rgw 概述Ceph 通过radosgw提供RES..._radosgw -c

前端数据可视化ECharts使用指南——制作时间序列数据的可视化曲线_echarts 时间序列-程序员宅基地

文章浏览阅读3.7k次,点赞6次,收藏9次。我为什么选择ECharts ? 本周学校课程设计,原本随机佛系选了一个51单片机来做音乐播放器,结果在粗略玩了CN-DBpedia两天后才回过神,课设还没有开始整。于是懒癌发作,碍于身上还有比赛的作品没交,本菜鸡对硬件也没啥天赋,所以就直接把题目切换成软件方面的题目。写python的同学选择了一个时间序列数据的可视化曲线程序设计题目,果真python在数据可视化这一点性能很优秀。..._echarts 时间序列

ApplicationEventPublisherAware事件发布-程序员宅基地

文章浏览阅读1.6k次。事件类:/** * *   * @className: EarlyWarnPublishEvent *   * @description:数据风险预警发布事件 *   * @param: *   * @return: *   * @throws: *   * @author: lizz *   * @date: 2020/05/06 15:31 * */public cl..._applicationeventpublisheraware

自定义View实现仿朋友圈的图片查看器,缩放、双击、移动、回弹、下滑退出及动画等_imageview图片边界回弹-程序员宅基地

文章浏览阅读1.2k次。如需转载请注明出处!点击小图片转到图片查看的页面在Android开发中很常用到,抱着学习和分享的心态,在这里写下自己自定义的一个ImageView,可以实现类似微信朋友圈中查看图片的功能和效果。主要功能需求:1.缩放限制:自由缩放,有最大和最小的缩放限制 2居中显示:.若图片没充满整个ImageView,则缩放过程将图片居中 3.双击缩放:根据当前缩放的状态,双击放大两倍或缩小到原来 4.单指_imageview图片边界回弹

PreScan第二课:构建实验_prescan坐标系-程序员宅基地

文章浏览阅读5.5k次,点赞8次,收藏37次。为了自己和他人学习的需要,建了一个PreScan的QQ群:613469333(已满)/ 778225322(可加),加群前请私聊群主(QQ:2059799865)加入。群管理需要花费时间和精力,为了鼓励管理员和群成员积极互动,入群需交¥9.99的群费。目录1 Conventions坐标系统2 Roads3 Path&trajectories路径和轨迹3.1 Pat..._prescan坐标系

三分钟带你掌握 CSS3 的新属性_采用css转换,边框阴影等新特性完成css3偏光图像画廊设计-程序员宅基地

文章浏览阅读3.8w次,点赞9次,收藏10次。1. css3简介CSS 用于控制网页的样式和布局,CSS3 是最新的CSS标准,CSS3 完全向后兼容,因此您不必改变现有的设计。浏览器通常支持 CSS2,但是现在大部分浏览器也实现了css3的很多特性。CSS3 被划分为模块。其中最重要的 CSS3 模块包括:选择器框模型背景和边框文本效果2D/3D 转换动画多列布局用户界面2. css3边框2.1 边框圆角Internet Explorer 9+ 支持 border-radius 和 box-shadow 属性。Fir_采用css转换,边框阴影等新特性完成css3偏光图像画廊设计

推荐文章

热门文章

相关标签