Android学习笔记二十七之ExpandableListView可折叠列表和StackView栈视图

Android学习笔记二十七之ExpandableListView可折叠列表和StackView栈视图

ExpandableListView可折叠列表

  这一节我们介绍第三个用适配器的控件,ExpandableListView可折叠列表。这个控件可以实现我们在QQ中非常常见好友分组功能,ExpandableListView是ListView的子类,用法跟ListView差不多,下面我们来学习这个控件的基本使用:

常用属性:

  • android:childDivider:指定各组内子类表项之间的分隔条,图片不会完全显示,分离子列表项的是一条直线
  • android:childIndicator:显示在子列表旁边的Drawable对象,可以是一个图像
  • android:childIndicatorEnd:子列表项指示符的结束约束位置
  • android:childIndicatorLeft:子列表项指示符的左边约束位置
  • android:childIndicatorRight:子列表项指示符的右边约束位置
  • android:childIndicatorStart:子列表项指示符的开始约束位置
  • android:groupIndicator:显示在组列表旁边的Drawable对象,可以是一个图像
  • android:indicatorEnd:组列表项指示器的结束约束位置
  • android:indicatorLeft:组列表项指示器的左边约束位置
  • android:indicatorRight:组列表项指示器的右边约束位置
  • android:indicatorStart:组列表项指示器的开始约束位置

实现ExpandableAdapter的三种方式:

  1. 自定义类继承BaseExpandableListAdpter实现ExpandableAdapter。
  2. 使用SimpleExpandableListAdpater将两个List集合包装成ExpandableAdapter
  3. 使用simpleCursorTreeAdapter将Cursor中的数据包装成SimpleCuroTreeAdapter

在这里,我们使用的是第一种方式,自定义一个类,实现BaseExpandableListAdapter,下面看具体实现:

布局代码:

item_group

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
    android:id="@+id/tv_group_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:layout_marginLeft="28dp"
    android:layout_marginTop="10dp"
    android:padding="8dp"
    android:text="张三"
    android:textColor="#000000"
    android:textSize="16sp" />

</LinearLayout>

item_child

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">

<ImageView
    android:id="@+id/iv_child_icon"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="8dp"
    android:padding="2dp"
    android:src="@mipmap/ic_launcher" />

<TextView
    android:id="@+id/tv_child_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginLeft="5dp"
    android:layout_marginTop="8dp"
    android:text="子节点"
    android:textColor="#330000"
    android:textSize="12sp" />

</LinearLayout>

activity_main布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.expandablelistviewdemo.MainActivity">

<ExpandableListView
    android:id="@+id/ex_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:childDivider="#E02D2F" />
</RelativeLayout>

自定义适配器代码:

package com.example.expandablelistviewdemo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * Created by Devin on 2016/7/12.
 */
public class CustomAdapter extends BaseExpandableListAdapter {

private List<Group> groupList;
private List<List<Child>> childList;
private Context mContext;

public CustomAdapter(Context mContext, List<Group> groupList, List<List<Child>> childList) {
    this.mContext = mContext;
    this.groupList = groupList;
    this.childList = childList;
}

/**
 * Gets the number of groups.
 *
 * @return
 */
@Override
public int getGroupCount() {
    return groupList.size();
}

/**
 * Gets the number of children in a specified group.
 *
 * @param i
 * @return
 */
@Override
public int getChildrenCount(int i) {
    return childList.get(i).size();
}

/**
 * Gets the data associated with the given group
 *
 * @param i
 * @return
 */
@Override
public Object getGroup(int i) {
    return groupList.get(i);
}

/**
 * Gets the data associated with the given child within the given group.
 *
 * @param i
 * @param i1
 * @return
 */
@Override
public Object getChild(int i, int i1) {
    return childList.get(i).get(i1);
}

/**
 * Gets the ID for the group at the given position.
 *
 * @param i
 * @return
 */
@Override
public long getGroupId(int i) {
    return i;
}

/**
 * Gets the ID for the given child within the given group.
 *
 * @param i
 * @param i1
 * @return
 */
@Override
public long getChildId(int i, int i1) {
    return i1;
}

/**
 * Indicates whether the child and group IDs are stable across changes to the underlying data.
 *
 * @return
 */
@Override
public boolean hasStableIds() {
    return false;
}

/**
 * Gets a View that displays the given group
 *
 * @param i
 * @param b
 * @param view
 * @param viewGroup
 * @return
 */
@Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
    GroupViewHolder groupViewHolder = null;
    if (view == null) {
        view = LayoutInflater.from(mContext).inflate(R.layout.item_group, viewGroup, false);
        groupViewHolder = new GroupViewHolder();
        groupViewHolder.tv_group_name = (TextView) view.findViewById(R.id.tv_group_name);
        view.setTag(groupViewHolder);
    } else {
        groupViewHolder = (GroupViewHolder) view.getTag();
    }
    groupViewHolder.tv_group_name.setText(groupList.get(i).getGroupName());
    return view;
}

/**
 * Gets a View that displays the data for the given child within the given group.
 *
 * @param i
 * @param i1
 * @param b
 * @param view
 * @param viewGroup
 * @return
 */
@Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
    ChildViewHolder childViewHolder = null;
    if (view == null) {
        view = LayoutInflater.from(mContext).inflate(R.layout.item_child, viewGroup, false);
        childViewHolder = new ChildViewHolder();
        childViewHolder.iv_child_icon = (ImageView) view.findViewById(R.id.iv_child_icon);
        childViewHolder.tv_child_name = (TextView) view.findViewById(R.id.tv_child_name);
        view.setTag(childViewHolder);
    } else {
        childViewHolder = (ChildViewHolder) view.getTag();
    }
    childViewHolder.iv_child_icon.setImageResource(R.mipmap.ic_launcher);
    childViewHolder.tv_child_name.setText(childList.get(i).get(i1).getChildName());
    return view;
}

/**
 * 这个方法需要返回true,不然不能实现子节点的点击事件
 * Whether the child at the specified position is selectable.
 *
 * @param i
 * @param i1
 * @return
 */
@Override
public boolean isChildSelectable(int i, int i1) {
    return true;
}

private static class GroupViewHolder {
    TextView tv_group_name;
}

private static class ChildViewHolder {
    ImageView iv_child_icon;
    TextView tv_child_name;
}
}

两个普通javaBean代码:

package com.example.expandablelistviewdemo;

/**
 * Created by Devin on 2016/7/12.
 */
public class Group {
private String groupName;

public Group() {
}

public Group(String groupName) {
    this.groupName = groupName;
}

public String getGroupName() {
    return groupName;
}

public void setGroupName(String groupName) {
    this.groupName = groupName;
}
}
package com.example.expandablelistviewdemo;

/**
 * Created by Devin on 2016/7/12.
 */
public class Child {
private String childName;

public Child() {
}

public Child(String childName) {
    this.childName = childName;
}


public String getChildName() {
    return childName;
}

public void setChildName(String childName) {
    this.childName = childName;
}
}

最后是activity代码:

package com.example.expandablelistviewdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {
private List<Group> groupList;
private List<List<Child>> childList;
private ExpandableListView ex_list;
private CustomAdapter customAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ex_list = (ExpandableListView) findViewById(R.id.ex_list);
    initData();
    customAdapter = new CustomAdapter(this, groupList, childList);
    ex_list.setAdapter(customAdapter);
    //子节点的点击事件
    ex_list.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
        @Override
        public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
            Toast.makeText(MainActivity.this, "你点击的是:" + childList.get(i).get(i1).getChildName(), Toast.LENGTH_SHORT).show();
            return true;
        }
    });
}

private void initData() {
    groupList = new ArrayList<>();
    childList = new ArrayList<>();

    groupList.add(new Group("载货汽车"));
    groupList.add(new Group("越野汽车"));
    groupList.add(new Group("自卸汽车"));
    groupList.add(new Group("专用汽车"));
    groupList.add(new Group("客车"));
    groupList.add(new Group("牵引车"));
    groupList.add(new Group("轿车"));
    groupList.add(new Group("半挂车"));


    List<Child> child1 = new ArrayList<>();
    child1.add(new Child("微型货车"));
    child1.add(new Child("轻型货车"));
    child1.add(new Child("中型货车"));
    child1.add(new Child("重型货车"));
    childList.add(child1);

    List<Child> child2 = new ArrayList<>();
    child2.add(new Child("轻型越野车"));
    child2.add(new Child("中型越野车"));
    child2.add(new Child("重型越野车"));
    child2.add(new Child("超重型越野车"));
    childList.add(child2);

    List<Child> child3 = new ArrayList<>();
    child3.add(new Child("轻型自卸车"));
    child3.add(new Child("中型自卸车"));
    child3.add(new Child("重型自卸车"));
    child3.add(new Child("矿用自卸车"));
    childList.add(child3);

    List<Child> child4 = new ArrayList<>();
    child4.add(new Child("箱式汽车"));
    child4.add(new Child("罐式汽车"));
    child4.add(new Child("起重举升车"));
    child4.add(new Child("仓栅式车"));
    child4.add(new Child("特种结构车"));
    child4.add(new Child("专用自卸车"));
    childList.add(child4);


    List<Child> child5 = new ArrayList<>();
    child5.add(new Child("微型客车"));
    child5.add(new Child("轻型客车"));
    child5.add(new Child("中型客车"));
    child5.add(new Child("大型客车"));
    child5.add(new Child("特大型客车"));
    childList.add(child5);

    List<Child> child6 = new ArrayList<>();
    child6.add(new Child("半挂牵引车"));
    child6.add(new Child("全挂牵引车"));
    childList.add(child6);

    List<Child> child7 = new ArrayList<>();
    child7.add(new Child("微型轿车"));
    child7.add(new Child("普通级轿车"));
    child7.add(new Child("中级轿车"));
    child7.add(new Child("中高级轿车"));
    child7.add(new Child("高级轿车"));
    childList.add(child7);

    List<Child> child8 = new ArrayList<>();
    child8.add(new Child("轻型半挂车"));
    child8.add(new Child("中型半挂车"));
    child8.add(new Child("重型半挂车"));
    child8.add(new Child("超重半挂车"));
    childList.add(child8);
}
}

最终实现效果图:

ExpandableListView控件就简单介绍到这里,这里只是基本的实现,有需求的可以扩展。

照例附上国内镜像API

下面我们学习另外一个控件StackView栈视图

StackView栈视图

  stackView是一个将一组View逐个展示给用户的控件,它是一组view的集合,这些view一个压着一个,view之间可以进行随意切换。下面我们通过实例了解StackView的使用方法

布局文件代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<StackView
    android:id="@+id/sk"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:loopViews="true" />

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_previous"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="前一张" />

    <Button
        android:id="@+id/btn_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="后一张" />

</LinearLayout>


</LinearLayout>

Activity代码:

package com.example.expandablelistviewdemo;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.StackView;

/**
 * Created by Devin on 2016/7/12.
 */
public class StackViewActivity extends AppCompatActivity {
private StackView sk;
private Button btn_previous;
private Button btn_next;
private int[] mColors = {Color.BLUE, Color.CYAN, Color.GRAY, Color.GREEN, Color.RED};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_stackview);
    sk = (StackView) findViewById(R.id.sk);
    btn_next = (Button) findViewById(R.id.btn_next);
    btn_previous = (Button) findViewById(R.id.btn_previous);
    ColorAdapter adapter = new ColorAdapter(getApplicationContext(), mColors);
    sk.setAdapter(adapter);
    btn_previous.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            sk.showPrevious();
        }
    });
    btn_next.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            sk.showNext();
        }
    });
}

/**
 * 自定义适配器
 */
private class ColorAdapter extends BaseAdapter {

    private Context mContext;

    private int[] mColors;

    public ColorAdapter(Context context, int[] colors) {
        mContext = context;
        mColors = colors;
    }

    public int getCount() {
        return mColors == null ? 0 : mColors.length;
    }

    public Object getItem(int position) {
        return mColors == null ? null : mColors[position];
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View view, ViewGroup parent) {
        LinearLayout.LayoutParams colorLayoutParams = new LinearLayout.LayoutParams(400, 400);

        LinearLayout colorLayout = new LinearLayout(mContext);
        colorLayout.setBackgroundColor(mColors[position]);
        colorLayout.setLayoutParams(colorLayoutParams);

        return colorLayout;
    }
}
}

最后实现效果图

可以通过手势拖拽切换,也可以点击按钮切换。StackView就简单介绍到这里,有需求的同学可以扩展,可以实现比较好的效果。StackView是androidAPI3.0以后的。

附上国内镜像API

下一节我们介绍一下Dialog控件

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值