Android Studio 二级树形列表---2(封装)---补充

   上一篇已经将二级树形列表做了封装,如果直接使用的话,看上去是没有任何问题了,但是bug还是有的,比如一级菜单下面没有子栏目的话,点击会出现app闪退现象。这个就是个很大的缺陷,在加上实现操作中不仅仅是简单的列表展示,还会有动态添加一个父节点,或者动态添加一个子节点,动态删除一个节点,又或者动态删除一个子节点。这些都是必须的。

  所以接下来我要把这些都要补充进去,这样用起来就基本满足一般的需求了。

 首先是LayerAdapterInterface 接口:

package com.example.appview.Common.TwoTree;

import android.view.View;
import android.view.ViewGroup;


public interface LayerAdapterInterface {
    /**
     *
     * @param groupPosition   第一层位置
     * @param convertView    第一层视图
     * @return
     */
    public View getGroupView(int groupPosition, View convertView);

    /**
     *
     * @param groupPosition  第一层组位置
     * @param childPosition   第二层view位置
     * @param convertView     第二层视图
     * @return
     */
    public View getChildView(int groupPosition, int childPosition, View convertView);

}

接下来是通用类的封装:

package com.example.appview.Common.TwoTree;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.appview.Demo;
import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.ThreeTreeModel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---‘\____
             .‘  \\|     |//  `.
            /  \\|||  :  |||//             /  _||||| -:- |||||-             |   | \\\  -  /// |   |
           | \_|  ‘‘\---/‘‘  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .‘  /--.--\  `. . __
      ."" ‘<  `.___\_<|>_/___.‘  >‘"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-‘======
                   `=---=‘
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            佛祖保佑       永无BUG
*/
public class LayerAdapterHelper<T1,T2,TControl extends LayerAdapterInterface> extends BaseExpandableListAdapter {
    public List<T1> oneTree; //二级列表第一层
    public List<List<T2>> twoTree;//二级列表第二层
    private TControl tControl; //这个是我们初始化控件用的类,这个是每一个Activity页面独有的,因为每个布局里面的内容可能不一样。
    private int RoneTree;//这个是二级列表第一层的页面布局  R.layout.布局页面
    private int RtwoTree;//这个是二级列表第二层的页面布局  R.layout.布局页面
    private Context context;
    LayoutInflater layoutInflater;
    public LayerAdapterHelper(Context context,List<T1> oneTree, List<List<T2>> twoTree,TControl tControl,int RoneTree,int RtwoTree){
        this.context=context;
        this.oneTree=oneTree;
        this.twoTree=twoTree;
        this.tControl=tControl;
        this.RoneTree=RoneTree;
        this.RtwoTree=RtwoTree;
        layoutInflater = LayoutInflater.from(context);
    }
    //保证每次只展开一组
    public void OnlyOne(ExpandableListView expandableListView){
        expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener(){
            @Override
            public void onGroupExpand(int groupPosition) {
                //保证每次只展开一组
                int count=expandableListView.getExpandableListAdapter().getGroupCount();
                for(int i=0;i<count; i++){
                    if(groupPosition != i){
                        expandableListView.collapseGroup(i);
                    }
                }
            }
        });
    }
    // 这里是控制如果列表没有孩子菜单不展开的效果
    public void IsChildenCount(ExpandableListView expandableListView){
        expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                // TODO Auto-generated method stub
                if (twoTree.get(groupPosition)==null) {// isEmpty没有
                    Toast.makeText(context, "你点击了~" + groupPosition + "~项", Toast.LENGTH_SHORT).show();
                    return true;
                } else {
                    return false;
                }
            }
        });
    }

    //向第一层树形中添加一个元素
    public void add(int groupPosition,T1 t) {
        if (oneTree == null) {
            oneTree= new ArrayList<>();
        }
         oneTree.add(groupPosition,t);
        twoTree.add(groupPosition,null);
        notifyDataSetChanged();
    }
    //向第二层树形中添加一个元素
    public void addItem(int groupPosition, T2 t) {
        if (twoTree.get(groupPosition) == null) {
            Toast.makeText(context, "你点击了~" + groupPosition + "~项", Toast.LENGTH_SHORT).show();
            List<T2> list=new ArrayList<>();
            list.add(t);
            twoTree.set(groupPosition,list);

        }else{
            twoTree.get(groupPosition).add(t);
        }

        notifyDataSetChanged();
    }
    //向第一层树形中特定位置移除一个元素
    public void remove(int position) {
        if (oneTree != null) {
            oneTree.remove(position);
        }
        notifyDataSetChanged();
    }
    //向第二层树形中特定位置移除一个元素
    public void remove(int groupPosition,int childPosition) {
        if (twoTree.get(groupPosition).get(childPosition)!=null) {
            twoTree.get(groupPosition).remove(childPosition);
        }
        notifyDataSetChanged();
    }
    //组数量
    @Override
    public int getGroupCount() {
        return oneTree.size();
    }
    //子View数量
    @Override
    public int getChildrenCount(int groupPosition) {
        return twoTree.get(groupPosition).size();
    }
    //获取组对象
    @Override
    public Object getGroup(int groupPosition) {
        return oneTree.get(groupPosition);
    }
    //获取子View对象
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return twoTree.get(groupPosition).get(childPosition);
    }
    // 组View下标
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
    //子View下标
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }
    //取得用于显示给定分组的视图. 这个方法仅返回分组的视图对象
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        convertView=  layoutInflater.inflate(RoneTree, null);
        return tControl.getGroupView(groupPosition,convertView);
    }
    //取得显示给定分组给定子位置的数据用的视图
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        convertView=  layoutInflater.inflate(RtwoTree, null);
        return tControl.getChildView(groupPosition,childPosition,convertView);
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {

        return false;
    }
}

实现类:

package com.example.appview;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import com.example.appview.Common.TwoTree.LayerAdapterHelper;
import com.example.appview.Common.TwoTree.LayerAdapterInterface;
import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Activity.Preject_ItemA_AddCaiJi;
import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Activity.Preject_ItemA_AlterJZ;
import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Activity.Preject_Item_AddJL;
import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.JiLouModel;
import com.example.appview.mian_page.Frament.Preject_Tance_Frament.ItemA_Model.SheiBeiModel;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Demo extends AppCompatActivity {
    private ExpandableListView expandableListView;
    private List<JiLouModel> jiLou=new ArrayList<>();
    private List<SheiBeiModel> sheiBei;
    private List<List<SheiBeiModel>> sheiBeiModels=new ArrayList<>();
    private LayerAdapterHelper<JiLouModel,SheiBeiModel,myControl> adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
       expandableListView = findViewById(R.id.expandable_listView);
        initdata();
        adapter=new LayerAdapterHelper<>(Demo.this,jiLou,sheiBeiModels,new myControl(),R.layout.preject_item_addcaiji_onetree,R.layout.preject_item_addcaiji_twotree);
        expandableListView .setAdapter(adapter);
         //保证每次只展开一组
        adapter.OnlyOne(expandableListView);
        // 这里是控制如果列表没有孩子菜单不展开的效果
        adapter.IsChildenCount(expandableListView);
    }
    //创造数据
    public void initdata(){

        jiLou.add(new JiLouModel(1,"机楼1","",new Date(System.currentTimeMillis())));
        jiLou.add(new JiLouModel(1,"机楼2","",new Date(System.currentTimeMillis())));
        jiLou.add(new JiLouModel(1,"机楼3","",new Date(System.currentTimeMillis())));

        sheiBei=new ArrayList<>();
        sheiBei.add(new SheiBeiModel(1,"设备1",""));
        sheiBei.add(new SheiBeiModel(1,"设备2",""));
        sheiBei.add(new SheiBeiModel(1,"设备3",""));

        sheiBeiModels.add(sheiBei);
        sheiBeiModels.add(null);//这个是如果父节点没有子节点的情况下,自己添加一个null内容
        sheiBei=new ArrayList<>();
        sheiBei.add(new SheiBeiModel(1,"设备4",""));
        sheiBei.add(new SheiBeiModel(1,"设备5",""));
        sheiBei.add(new SheiBeiModel(1,"设备6",""));

        sheiBeiModels.add(sheiBei);


    }
  class myControl implements LayerAdapterInterface{
      @Override
      public View getGroupView(int groupPosition, View convertView) {
          TextView textView = convertView.findViewById(R.id.preject_item_caijiqi_onetree);
          textView.setText(adapter.oneTree.get(groupPosition).getJiLouName());
          LinearLayout linearLayout=convertView.findViewById(R.id.preject_item_imagecaiji_onetree);
          linearLayout.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {

                 getOne(linearLayout,groupPosition);
              }
          });
          return convertView;
      }

      @Override
      public View getChildView(int groupPosition, int childPosition, View convertView) {
          convertView.setPadding(50,5,0,5);
          TextView textView = convertView.findViewById(R.id.preject_item_dianbiao);
          textView.setText(adapter.twoTree.get(groupPosition).get(childPosition).getSheBeiName());
          LinearLayout linearLayout=convertView.findViewById(R.id.preject_item_layoutcaozuo_twotree);

          linearLayout.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
            getTwo(linearLayout,groupPosition,childPosition);
              }
          });
          return convertView;
      }
  }
    private void getOne(LinearLayout linearLayout, int position){
        View popupView = View.inflate(Demo.this, R.layout.preject_item_pop_alter, null);
        Button btn1=popupView.findViewById(R.id.preject_item_alter_btn1);
        Button btn2=popupView.findViewById(R.id.preject_item_alter_btn2);
        btn1.setText("添加机楼");
        btn2.setText("删除");
        GradientDrawable drawable1 =(GradientDrawable)btn1.getBackground();
        drawable1.setColor(getResources().getColor(R.color.preject4));
        GradientDrawable drawable2 =(GradientDrawable)btn2.getBackground();
        drawable2.setColor(getResources().getColor(R.color.preject3));
        PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setAnimationStyle(R.anim.move_pop_left_in);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        int popupWidth = popupView.getMeasuredWidth();
        int popupHeight =  popupView.getMeasuredHeight();
        int[] location = new int[2];
        linearLayout.getLocationOnScreen(location);
        popupWindow.showAtLocation(linearLayout, Gravity.NO_GRAVITY, location[0], location[1]);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.dismiss();

             //   adapter.add(0,new JiLouModel(1,"机楼1","",new Date(System.currentTimeMillis())));
            //
                adapter.addItem(position,new SheiBeiModel(1,"设备4",""));
            }
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.dismiss();

            }
        });

    }
    private void getTwo(LinearLayout linearLayout, int position,int childenPosition){
        View popupView = View.inflate(Demo.this, R.layout.preject_item_pop_alter, null);
        Button btn1=popupView.findViewById(R.id.preject_item_alter_btn1);
        Button btn2=popupView.findViewById(R.id.preject_item_alter_btn2);
        btn1.setText("添加机楼");
        btn2.setText("删除");
        btn1.setVisibility(btn1.GONE);
        GradientDrawable drawable1 =(GradientDrawable)btn1.getBackground();
        drawable1.setColor(getResources().getColor(R.color.preject4));
        GradientDrawable drawable2 =(GradientDrawable)btn2.getBackground();
        drawable2.setColor(getResources().getColor(R.color.preject3));
        PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setAnimationStyle(R.anim.move_pop_left_in);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        int popupWidth = popupView.getMeasuredWidth();
        int popupHeight =  popupView.getMeasuredHeight();
        int[] location = new int[2];
        linearLayout.getLocationOnScreen(location);
        popupWindow.showAtLocation(linearLayout, Gravity.NO_GRAVITY, location[0], location[1]);

        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popupWindow.dismiss();

            }
        });

    }

}

布局页面就不再放在去了,和上一篇一样。

最后看一下效果图:

Android Studio 二级树形列表---2(封装)---补充

Android Studio 二级树形列表---2(封装)---补充

上一篇:Android笔记--自定义控件 Toast


下一篇:2021金三银四面试季!《Android面试题及解析》分享给大家,大厂面试必备技能