ExpandableListView效果实现

先上第一种示意图:
这里写图片描述

这种效果,大家都很常见,其实现代码如下:

**第一步:**activity界面

private RadioButton mHotQue;
    private RadioButton mCateQue;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHotQue = (RadioButton) findViewById(R.id.question_hot);
        mCateQue = (RadioButton) findViewById(R.id.question_category);
        //设置默认第一次进来热门问题为选择状态
        mHotQue.setChecked(true);
        onClick(mHotQue);
        //设置点击事件
        mHotQue.setOnClickListener(this);
        mCateQue.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Fragment fragment = null;
        switch (v.getId()) {
            case R.id.question_hot :
                //热门问题
                fragment = QuestionHotFragment.newInstance();
                break;
            case R.id.question_category :
                //分类问题,具体操作就不详述
                fragment = QuestionCategoryFragment.newInstance();
                break;
        }
            //切换Fragment管理
            if(fragment != null) {
                FragmentManager manager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = manager.beginTransaction();
                fragmentTransaction.replace(R.id.rl_container,fragment);
                fragmentTransaction.commit();
            }
    }

**第二步:**activity的布局

<LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <!--compile 'info.hoang8f:android-segmented:1.0.6'
      app:sc_border_width="1.5dp"
        app:sc_corner_radius="5dp" 为内部分装好的属性-->
    <info.hoang8f.android.segmented.SegmentedGroup
        android:background="#ffffff"
        android:padding="10dp"
        app:sc_border_width="1.5dp"
        app:sc_corner_radius="5dp"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!--复用style文件-->
        <RadioButton
            android:id="@+id/question_hot"
            style="@style/SegmentRadioButton"
            android:text="热门问题"
            android:textSize="16sp"
            android:paddingBottom="7dp"
            android:paddingTop="7dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"/>
        <RadioButton
            android:id="@+id/question_category"
            style="@style/SegmentRadioButton"
            android:text="分类问题"
            android:textSize="16sp"
            android:paddingTop="7dp"
            android:paddingBottom="7dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"/>
    </info.hoang8f.android.segmented.SegmentedGroup>

    <FrameLayout
        android:id="@+id/rl_container"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

第三步:热门问题的fragment

public class QuestionHotFragment extends Fragment{

    private ExpandableListView mListView;
    //缓存的fragment View
    private View mView;
    private QuestionAdapter mQuestionAdapter;

    public static Fragment newInstance() {
        QuestionHotFragment fragment = new QuestionHotFragment();
        return fragment;
    }

    //避免每次开启fragment都需要创建fragment
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
      if(mView == null) {
          mView = inflater.inflate(R.layout.fragment_hot_question,container,false);
          mListView = (ExpandableListView) mView.findViewById(R.id.question_listview);
      }
        // 缓存的rootView需要判断是否已经被加过parent,如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误
        ViewGroup parent = (ViewGroup) mView.getParent();
        if(parent != null) {
            parent.removeView(mView);
        }
        return mView;
    }

    //视图创建后的操作
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mQuestionAdapter = new QuestionAdapter(getActivity());
        mListView.setAdapter(mQuestionAdapter);
        //去除父节点图标
        mListView.setGroupIndicator(null);
        initListener();
    }

    private void initListener() {
        //添加监听
        //ExpandableListView的子元素添加点击监听
        mListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                mListView.collapseGroup(groupPosition);
                return false;
            }
        });

        //ExpandableListView的组展开监听
        mListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                for (int i = 0; i < mQuestionAdapter.getGroupCount(); i++) {
                    if (groupPosition != i && mListView.isGroupExpanded(groupPosition)) {
                        mListView.collapseGroup(i);
                    }
                }
            }
        });

        //ExpandableListView的组聚拢监听
        mListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
            @Override
            public void onGroupCollapse(int groupPosition) {

            }
        });

        //ExpandableListView的组点击监听,返回true表示不可点击,返回false可以点击
        mListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                return false;
            }
        });
    }
}

第四步:热门问题的Adapter

public class QuestionAdapter extends BaseExpandableListAdapter{
    private Context mContext;

    // 设置组视图的显示文字
    private String[] summaryQuestion = new String[]{"建议配比中的1R、2R、3R分别代表什么含义?",
            "铜板能用来做什么?是否随时都可以使用?"};
    // 子视图显示文字,二级数组
    private String[][] detailDesc = new String[][]{
            {"风险等级是根据产品投资方向、合作伙伴的资金实力、理财期限、该产品是否哦承诺回购、是否有担保、担保公司实力" +
                    "资质等因素做出的等级区分。1R:超低风险,适合做配置安全垫 2R:较低风险,适合做部分资产配置 3R:有一定风险,请" +
                    "根据个人实际情况做资产配置"},
            {"铜板可以兑换成话费或者集分宝哦,同事目前还支持在铜板商城兑换加息券和代金券。话费:2000铜板起兑换,换算公式:" +
                    "1000铜板=10元话费,以此类推;集分宝:1铜板起兑换,换算公式:1000铜板=1000集分宝,以此类推,兑换前需绑定支付宝账号。" +
                    "积分商城兑换可具体查看详细兑换规则。"}

    };

    //定义一个获取文字视图信息的方法
    TextView getTextView(int textSize, int textColor){
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lp.gravity = Gravity.CENTER_VERTICAL;
        TextView textView = new TextView(mContext);
        textView.setLayoutParams(lp);
        textView.setGravity(Gravity.CENTER_VERTICAL);
        textView.setPadding(DensityUtils.dip2px(mContext, 10), DensityUtils.dip2px(mContext, 15), DensityUtils.dip2px(mContext, 2),
                DensityUtils.dip2px(mContext, 15));
        textView.setTextColor(textColor);
        textView.setTextSize(textSize);
        return textView;
    }

    //定义一个获得图片信息的方法
    ImageView getImageView(){
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lp.gravity = Gravity.CENTER_VERTICAL;
        ImageView imageView = new ImageView(mContext);
        imageView.setLayoutParams(lp);
        imageView.setPadding(0,0,0,0);
        return imageView;
    }
    public QuestionAdapter(Context context) {
        this.mContext = context;
    }

    //获取组的数量
    @Override
    public int getGroupCount() {
        return summaryQuestion.length;
    }

    //获取每个分组的长度
    @Override
    public int getChildrenCount(int groupPosition) {
        return detailDesc[groupPosition].length;
    }

    //获得每个组的对象
    @Override
    public Object getGroup(int groupPosition) {
        return summaryQuestion[groupPosition];
    }

    //获取每个分组下面的每个具体的对象
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return detailDesc[groupPosition][childPosition];
    }

    //获得每个组的id
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    //得到其分组每个的id
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    //主要是用来判断ExpandableListView内容id是否有效的(返回true or false),
    // 系统会跟据id来确定当前显示哪条内容,也就是firstVisibleChild的位置
    @Override
    public boolean hasStableIds() {
        return false;
    }

    //得到组视图
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupViewHodler viewHodler = null;
        if(convertView == null) {
            //利用容器来添加视图(或者也可以直接加载布局视图--inflate(R.layout.resID))
            LinearLayout linearLayout = new LinearLayout(mContext);
            linearLayout.setBackgroundColor(Color.parseColor("#ffffff"));
            linearLayout.setOrientation(LinearLayout.HORIZONTAL);
            TextView textView = getTextView(16, mContext.getResources().getColor(R.color.black));
            //添加文本视图
            linearLayout.addView(textView);

            //添加图片视图
            ImageView imageView = getImageView();
            linearLayout.addView(imageView);

            //进行赋值操作
            convertView = linearLayout;
            viewHodler = new GroupViewHodler();
            viewHodler.mTextView = textView;
            viewHodler.mImageView = imageView;
            convertView.setTag(viewHodler);
        }else {
            viewHodler = (GroupViewHodler) convertView.getTag();
        }

        viewHodler.mTextView.setText(getGroup(groupPosition).toString());
        //是否展开
        if(isExpanded) {
            //向下图标
            viewHodler.mImageView.setImageResource(R.drawable.arrow_down);
        }else {
            //向上图标
            viewHodler.mImageView.setImageResource(R.drawable.arrow_up);
        }
        return convertView;
    }

    //获取到分组视图
    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ChildViewHolder viewHolder = null;
        if (convertView == null) {
            LinearLayout childLayout = new LinearLayout(
                    mContext);
            childLayout.setOrientation(LinearLayout.VERTICAL);
            childLayout.setBackgroundColor(Color.parseColor("#f2f2f2"));
            TextView textView = getTextView(16, mContext.getResources().getColor(R.color.black));
            childLayout.addView(textView);

            convertView = childLayout;
            viewHolder = new ChildViewHolder();
            viewHolder.mTextView = textView;
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ChildViewHolder)convertView.getTag();
        }
        //填充数据
        viewHolder.mTextView.setText(getChild(groupPosition,childPosition).toString());
        return convertView;
    }

    //用来判断某Group某个child是否可可选。我们可以添加条件控制某Group某个child可点或不可点击。
    // 当不加任何条件直接返回false,所有的组的child均不可点击。返回true,表示所有的分组都可以点击
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    //组ViewHodler
    public static class GroupViewHodler{
        public TextView mTextView;
        public ImageView mImageView;
    }
    //分组ViewHodler
    public static class ChildViewHolder{
        public TextView mTextView;
    }
}

第五步:热门问题的fragment

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <ExpandableListView
        android:id="@+id/question_listview"
        android:listSelector="@null"
        android:scrollbars="none"
        android:cacheColorHint="#00000000"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

别忘了,在项目中引用:
compile ‘info.hoang8f:android-segmented:1.0.6’

还有另外一种示意图:就是全部展开,且不可点击,如图:
这里写图片描述

以上实现地方法很简单,同样重复第一种情况的5个步骤,但是需要做些修改
修改一:改变isChildSelectable的返回值状态

@Override
    public boolean isChildSelectable(int groupPosition,
                                     int childPosition) {
        return false;
    }

修改二:如下

//ExpandableListView的组点击监听,返回true表示不可点击
        mListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                 return true;
            }
        });

修改三:如下在设置adapter之后,添加如下循环即可

mListView.setAdapter(mQuestionAdapter);
//添加此句话即可实现全部展开
        for (int i = 0; i < mQuestionAdapter.getGroupCount(); i++) {
            mListView.expandGroup(i);
        }

以上,就是二种状态的不同实现

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值