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移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合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)]
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!