GridView实现多选,全选,反选等功能

先看看效果
GridView实现多选,全选,反选等功能_第1张图片

我这里用到了数据库来储存选择的数据,数据库的简单实用我在前面的博客写过了,这里就不多说了,直接贴代码

数据库操作类的代码

package com.duanlian.gridviewmultiplechoicedemo.database;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * 数据库
 */

public class DataBase extends SQLiteOpenHelper {
    //数据库名字
    public static final String DB_NAME = "DaiMeng.db";
    //数据库版本
    public static final int DB_VERSION = 1;
    //表名,关注的表,用来储存用户选择过的新闻频道
    public static final String TABLE_NAME = "channel";
    public static DataBase mDataBase;

    /**
     * 单例模式返回数据库
     *
     * @param context 上下文
     * @return 数据库对象
     */
    public static DataBase getInstances(Context context) {
        if (mDataBase == null) {
            return new DataBase(context);
        } else {
            return mDataBase;
        }
    }


    //上下文,数据库名字,数据库工厂,版本号
    public DataBase(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    //此方法中创建表
    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        //赛事id,
        sqLiteDatabase.execSQL("create table" + " " + TABLE_NAME + "(id INTEGER PRIMARY KEY AUTOINCREMENT,channel text);");

    }

    /**
     * 用来更新数据库版本的
     * onCreate方法只是在第一次安装app的时候会调用,之后的数据库要更改的话,必须使用数据库版本上升,或者卸载了重新安装
     *
     * @param sqLiteDatabase 数据库
     * @param oldVersion     老的版本号
     * @param newVersion     更新后的版本号
     */
    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        if (newVersion > oldVersion) {
            //删除老表
            sqLiteDatabase.execSQL("drop" + TABLE_NAME);
            //重新创建表
            onCreate(sqLiteDatabase);
        }

    }

    /**
     * 创建一个用来插入数据的方法
     */
    public void insert(String channel) {
        //让数据库可写
        SQLiteDatabase database = getWritableDatabase();
        /*
        类似于HashMap 都有键值对
        key 对应的列表中的某一列的名称,字段
        value 对应字段要插入的值
         */
        ContentValues values = new ContentValues();
        values.put("channel", channel);
        //插入
        database.insert(TABLE_NAME, null, values);
        //插入完成后关闭,以免造成内存泄漏
        database.close();

    }


    /**
     * 创建一个查找数据库的方法
     * 各个参数的意义说明:
     * 参数table:表名称
     * 参数columns:列名称数组
     * 参数selection:条件字句,相当于where
     * 参数selectionArgs:条件字句,参数数组
     * 参数groupBy:分组列
     * 参数having:分组条件
     * 参数orderBy:排序列
     * 参数limit:分页查询限制
     * 参数Cursor:返回值,相当于结果集ResultSet
     * Cursor是一个游标接口,提供了遍历查询结果的方法,如移动指针方法move(),获得列值方法getString()等.
     */
    public Cursor query() {
        //数据库可读
        SQLiteDatabase database = getReadableDatabase();
        //查找
        Cursor query = database.query(TABLE_NAME, null, null, null, null, null, null);
        return query;
    }

    /**
     * 创建一个删除数据的方法,传入的参数越多,删除时越精确的找到要删除的哪一行
     */
    public void delete(String channel) {
        SQLiteDatabase database = getWritableDatabase();
        /*
        //当条件满足gameid = 传入的参数的时候,就删除那整行数据,有可能有好几行都满足这个条件,满足的全部都删除
         */
        String where = "channel = ?";
        //删除条件的参数
        String[] whereArgs = {channel + ""};
        database.delete(TABLE_NAME, where, whereArgs);
        database.close();
    }


    /**
     * 创建一个修改数据的方法
     */
    public void updata(String channel) {
        SQLiteDatabase database = getWritableDatabase();
//        update(String table,ContentValues values,String  whereClause, String[]  whereArgs)
        String where = "channel = ?";
        String[] whereArgs = {channel + ""};
        ContentValues values = new ContentValues();
        values.put("channel", channel);
        database.update(TABLE_NAME, values, where, whereArgs);
        database.close();
    }
}

主Activity布局文件


<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.duanlian.gridviewmultiplechoicedemo.MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:onClick="buttonClick"
        android:text="去筛选"/>

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_below="@+id/button"
        android:gravity="center"
        android:text="下面是选择的结果"/>

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tv"/>
RelativeLayout>

上面一个按钮是用来跳转到筛选的Activity的
下面一个ListView是用来显示筛选完成得到筛选后的结果的
GridView实现多选,全选,反选等功能_第2张图片

主Activity的逻辑代码

package com.duanlian.gridviewmultiplechoicedemo;

import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;

import com.duanlian.gridviewmultiplechoicedemo.database.DataBase;

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

public class MainActivity extends AppCompatActivity {
    private ListView mListView;
    private ListViewAdapter mListViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

    }

    private void initView() {
        mListView = (ListView) findViewById(R.id.listview);
        mListViewAdapter = new ListViewAdapter(this, getData());
        mListView.setAdapter(mListViewAdapter);
    }

    /**
     * button的点击监听
     * @param view
     */
    public void buttonClick(View view) {
        //跳转到筛选的activity
        Intent intent = new Intent(MainActivity.this, MultipleChoiceActivity.class);
        //通过带返回值的跳转来的到下一个页面带过来的值
        startActivityForResult(intent,888);
    }
    /**
     * 通过查找数据库,拿到里面的数据
     */
    private List getData() {
        List list = new ArrayList<>();
        Cursor query = DataBase.getInstances(this).query();
        if (query.moveToFirst()) {
            do {
                String channel = query.getString(query.getColumnIndex("channel"));
                list.add(channel);
            } while (query.moveToNext());
        }
        //关闭查询游标
        query.close();
        return list;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 888 && resultCode == 999) {
            mListViewAdapter = new ListViewAdapter(this, getData());
            mListView.setAdapter(mListViewAdapter);
        }
    }
}

筛选页面的布局


<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_add_channel"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
>

    <RelativeLayout
        android:id="@+id/relative_top"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:paddingRight="10dp">

        <TextView
            android:id="@+id/add_channel_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:paddingLeft="10dp"
            android:text="选择"/>

        <TextView
            android:id="@+id/tv_invert"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:gravity="center_vertical"
            android:onClick="addChannel"
            android:text="反选"
            android:textColor="@color/black_444444"
            android:textSize="16sp"/>

        <TextView
            android:id="@+id/tv_line"
            android:layout_width="1dp"
            android:layout_height="14dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:layout_toLeftOf="@+id/tv_invert"
            android:background="@color/black_444444"
            android:clickable="true"
            android:gravity="center_vertical"
            />

        <TextView
            android:id="@+id/tv_check_all"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_toLeftOf="@+id/tv_line"
            android:clickable="true"
            android:gravity="center_vertical"
            android:onClick="addChannel"
            android:text="全选"
            android:textColor="@color/black_444444"
            android:textSize="16sp"/>
    RelativeLayout>


    <GridView
        android:id="@+id/gv_channel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/rl_bottom"
        android:layout_below="@+id/relative_top"
        android:background="#f0f0f0"
        android:numColumns="3"
        android:paddingTop="10dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:scrollbars="none"/>

    <RelativeLayout
        android:id="@+id/rl_bottom"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:paddingLeft="30dp"
        android:paddingRight="30dp">

        <Button
            android:id="@+id/btn_sure"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:layout_centerInParent="true"
            android:onClick="addChannel"
            android:text="确定"
            android:textSize="16sp"/>
    RelativeLayout>
RelativeLayout>

效果

GridView实现多选,全选,反选等功能_第3张图片

筛选页面

package com.duanlian.gridviewmultiplechoicedemo;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;

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

/**
 * 筛选页面
 */
public class MultipleChoiceActivity extends AppCompatActivity {
    private GridView mGridView;
    private GridViewAdapter mGridViewAdapter;
    private List mList;
    private String[] channel = {"娱乐", "财经", "军事", "足球", "篮球", "体育", "电影", "房产",
            "电台", "汽车", "手机", "时尚", "论坛", "彩票", "暴雪", "社会", "情感", "教育", "家居", "游戏",
            "科技", "数码", "旅游", "周杰伦", "亲情", "段炼", "Android", "IOS", "移动", "星座", "风水"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_multiple_choice_avtivity);
        initView();
    }

    private void initView() {
        mGridView = (GridView) findViewById(R.id.gv_channel);
        //添加数据
        mList = new ArrayList<>();
        for (int i = 0; i < channel.length; i++) {
            mList.add(channel[i]);
        }
        mGridViewAdapter = new GridViewAdapter(this, mList);
        mGridView.setAdapter(mGridViewAdapter);
        //GridView的item的点击事件
        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                //将当前点击的position传递过去做相应的状态改变
                mGridViewAdapter.choiceState(position);
            }
        });

    }

    /**
     * button点击事件的监听
     *
     * @param view
     */
    public void addChannel(View view) {
        switch (view.getId()) {
            case R.id.tv_check_all://全选
                mGridViewAdapter.changeState(2);
                break;
            case R.id.tv_invert://反选
                mGridViewAdapter.changeState(1);
                break;
            case R.id.btn_sure://确定按钮
                setResult(999,new Intent());
                finish();
                break;
        }
    }
}

状态改变的逻辑主要是在GridView的Adapter里面

package com.duanlian.gridviewmultiplechoicedemo;

import android.content.Context;
import android.database.Cursor;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.duanlian.gridviewmultiplechoicedemo.database.DataBase;

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

/**
 * gridView的adapter
 */
public class GridViewAdapter extends BaseAdapter {
    private Context mContext;
    private List channelList;
    private boolean[] isCheck;
    ViewHolder holder = null;
    //数据库
    DataBase dataBase;


    public GridViewAdapter(Context context, List channelList) {
        this.mContext = context;
        this.channelList = channelList;
        dataBase = new DataBase(context);
        //给数组设置大小,并且全部赋值为false
        if (channelList != null) {
            isCheck = new boolean[channelList.size()];
            for (int i = 0; i < channelList.size(); i++) {
                isCheck[i] = false;
            }
        }
    }

    @Override
    public int getCount() {
        return channelList != null ? channelList.size() : null;
    }

    @Override
    public Object getItem(int position) {
        return channelList != null ? channelList.get(position) : null;
    }

    @Override
    public long getItemId(int position) {
        return channelList != null ? position : 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = View.inflate(mContext, R.layout.item_gridview, null);
            holder.textView = (TextView) convertView.findViewById(R.id.tv_league);
            holder.mRelativeLayout = (RelativeLayout) convertView.findViewById(R.id.ll_competition);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        //给item赋值
        holder.textView.setText(channelList.get(position));
        /*
        数组里面放置的是所有的position的是否选中的状态
        如果当前position的状态是true就是选中状态
        如果当前position的状态是false就不是选中状态
         */
        if (isCheck[position]) {
            holder.mRelativeLayout.setBackgroundResource(R.drawable.grid_shap_two);
            holder.textView.setTextColor(mContext.getResources().getColor(R.color.colorAccent));
        } else {
            holder.mRelativeLayout.setBackgroundResource(R.drawable.grid_shap_one);
            holder.textView.setTextColor(mContext.getResources().getColor(R.color.black_444444));

        }
        /**
         * 刚进去就去拿数据库里面以前选中的数据
         * 如果数据库拿到的数据和集合里面取出来的数据一样,说明当前position处于选中状态,
         * 并且数组里面的当前position也要赋值true
         */
        List choiceChannel = getData();
        for (int j = 0; j < choiceChannel.size(); j++) {
            if (channelList.get(position).equals(choiceChannel.get(j))) {
                holder.mRelativeLayout.setBackgroundResource(R.drawable.grid_shap_two);
                holder.textView.setTextColor(mContext.getResources().getColor(R.color.colorAccent));
                isCheck[position] = true;
            }

        }
        return convertView;
    }

    /**
     * 改变某一个选项的状态
     * @param post
     */
    public void choiceState(int post) {
        /**
         *  传递过来所点击的position,如果是本身已经是选中状态,就让他变成不是选中状态,
         *  如果本身不是选中状态,就让他变成选中状态
         */

        isCheck[post] = isCheck[post] == true ? false : true;
        if (isCheck[post]) {
            //如果当前position是选中状态的的position也就是当前position是true,就把集合当前position的值存入数据库
            dataBase.insert(channelList.get(post));
        } else {
            //反之则从数据库里面删除
            dataBase.delete(channelList.get(post));
        }
        this.notifyDataSetChanged();
    }

    /**
     * 改变所有的选项框的状态,也就是全选和反选
     * @param type
     */
    public void changeState(int type) {
        if (type == 1) {//反选
            //把数组里面的值全部便利一遍,如果是选中,就变成不选中,如果没选中就变成选中
            for (int i = 0; i < channelList.size(); i++) {
                isCheck[i] = isCheck[i] == true ? false : true;
                if (isCheck[i]) {
                    dataBase.insert(channelList.get(i));
                } else {
                    dataBase.delete(channelList.get(i));
                }
            }
        }
        else if (type == 2) {//全选
            //全部变成选中状态
            for (int i = 0; i < channelList.size(); i++) {
                isCheck[i] = true;
                if (isCheck[i]) {
                    dataBase.insert(channelList.get(i));
                } else {
                    dataBase.delete(channelList.get(i));
                }
            }
        }

        notifyDataSetChanged();

    }

    static class ViewHolder {
        TextView textView;
        RelativeLayout mRelativeLayout;

    }

    /**
     * 通过查找数据库,拿到里面的数据
     */
    private List getData() {
        List list = new ArrayList<>();
        Cursor query = DataBase.getInstances(mContext).query();
        if (query.moveToFirst()) {
            do {
                String channel = query.getString(query.getColumnIndex("channel"));
                list.add(channel);
            } while (query.moveToNext());
        }
        //关闭查询游标
        query.close();
        return list;
    }

}

然后是用来显示筛选完成后的结果的ListView的Adapter

package com.duanlian.gridviewmultiplechoicedemo;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.List;

/**
 * ListView的Adapter
 */
public class ListViewAdapter extends BaseAdapter {
    private Context mContext;
    private List channelList;
    ViewHolder holder = null;


    public ListViewAdapter(Context context, List channelList) {
        this.mContext = context;
        this.channelList = channelList;
    }

    @Override
    public int getCount() {
        return channelList != null ? channelList.size() : null;
    }

    @Override
    public Object getItem(int position) {
        return channelList != null ? channelList.get(position) : null;
    }

    @Override
    public long getItemId(int position) {
        return channelList != null ? position : 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = View.inflate(mContext, R.layout.item_gridview, null);
            holder.textView = (TextView) convertView.findViewById(R.id.tv_league);
            holder.mRelativeLayout = (RelativeLayout) convertView.findViewById(R.id.ll_competition);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        //给item赋值
        holder.textView.setText(channelList.get(position));
        return convertView;
    }


    static class ViewHolder {
        TextView textView;
        RelativeLayout mRelativeLayout;

    }


}

更多细节请下载demo
点击下载demo

你可能感兴趣的:(android,常用控件)