天天看點

Android UI(CheckBox)詳解

目錄:

1.CheckBox應用場景

2.CheckBox一般使用

3.自定義CheckBox

4.CheckBox在ListView中的問題

1.CheckBox應用場景

CheckBox應用于可多選的場景,比如多檔案的增删改查,移動,以及愛好啊這些的選擇等等

2.CheckBox簡單使用

    1)主布局檔案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingRight="10dp"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
 tools:context=".MainActivity">


    <TextView android:text="愛好:"
        android:textSize="24sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="音樂"
            android:id="@+id/chb_music"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginTop="10dp"
            android:checked="false" />


        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="遊戲"
            android:id="@+id/chb_game"
            android:layout_below="@+id/chb_music"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true" />


        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="旅遊"
            android:id="@+id/chb_trip"
            android:layout_alignTop="@+id/chb_music"
            android:layout_alignRight="@+id/chb_film"
            android:layout_alignLeft="@+id/chb_film" />


        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="看電影"
            android:id="@+id/chb_film"
            android:layout_below="@+id/chb_trip"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true" />
    </RelativeLayout>
    <Button
        android:id="@+id/end"
        android:text="完成"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:paddingTop="10dp"
        android:id="@+id/result_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</LinearLayout>           

    2)Java檔案

package com.example.elimy.checkboxui;


import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;


import java.util.ArrayList;


public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {
    private CheckBox musicCkb;
    private CheckBox tripCkb;
    private CheckBox filmCkb;
    private CheckBox gameCkb;
    private TextView result_tv;
    private Button endBtn;
    //愛好數組
    ArrayList<String> hobbies=new ArrayList<String>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        musicCkb = (CheckBox) findViewById(R.id.chb_music);
        tripCkb = (CheckBox) findViewById(R.id.chb_trip);
        filmCkb = (CheckBox) findViewById(R.id.chb_film);
        gameCkb = (CheckBox) findViewById(R.id.chb_game);
        result_tv = (TextView) findViewById(R.id.result_tv);
        endBtn= (Button) findViewById(R.id.end);
        //設定監聽器
        musicCkb.setOnCheckedChangeListener(this);
        tripCkb.setOnCheckedChangeListener(this);
        filmCkb.setOnCheckedChangeListener(this);
        gameCkb.setOnCheckedChangeListener(this);
        //為button設定監聽器
        endBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                StringBuilder sb=new StringBuilder();
              for (int i =0;i<hobbies.size();i++) {
                  //把選擇的愛好添加到string尾部
                  if(i==(hobbies.size()-1))
                  {
                      sb.append(hobbies.get(i));
                  }else {
                      sb.append(hobbies.get(i)+",");
                  }


              }
                //顯示選擇結果
                result_tv.setText("你選擇了:"+sb);
            }
        });
    }


    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked){
            //添加到愛好數組
            hobbies.add(buttonView.getText().toString().trim());
        }else {
            //從數組中移除
            hobbies.remove(buttonView.getText().toString().trim());
        }


    }
}           

3)效果截圖

Android UI(CheckBox)詳解

3.自定義CheckBox

注:自定義的方式有很多種,在此就實作一種,如果夥伴們感興趣,可以去我前面的文章中檢視其他幾種實作方式

1)導入背景圖檔(原諒我盜圖,當然隻做自己學習所用,夥伴們可别學我)

2)實作checkbox_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/checked" android:state_checked="true"></item>
    <item android:drawable="@drawable/unchecked" android:state_checked="false"></item>
</selector>           

3)主布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingRight="10dp"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
 tools:context=".MainActivity">


    <TextView android:text="愛好:"
        android:textSize="24sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="音樂"
            android:id="@+id/chb_music"
            android:drawableLeft="@drawable/checkbox_selector"
            android:drawablePadding="5dp"
            android:button="@null"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_marginTop="10dp"
            android:checked="false" />


        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="遊戲"
            android:drawableLeft="@drawable/checkbox_selector"
            android:drawablePadding="5dp"
            android:button="@null"
            android:id="@+id/chb_game"
            android:layout_below="@+id/chb_music"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true" />


        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="旅遊"
            android:drawableLeft="@drawable/checkbox_selector"
            android:drawablePadding="5dp"
            android:button="@null"
            android:id="@+id/chb_trip"
            android:layout_alignTop="@+id/chb_music"
            android:layout_alignRight="@+id/chb_film"
            android:layout_alignLeft="@+id/chb_film" />


        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="看電影"
            android:drawableLeft="@drawable/checkbox_selector"
            android:drawablePadding="5dp"
            android:button="@null"
            android:id="@+id/chb_film"
            android:layout_below="@+id/chb_trip"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true" />
    </RelativeLayout>
    <Button
        android:id="@+id/end"
        android:text="完成"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:paddingTop="10dp"
        android:id="@+id/result_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
</LinearLayout>           

4)Java檔案(可參考2)

5)效果截圖

Android UI(CheckBox)詳解

4.CheckBox在ListView中的問題

注:我們經常會有需求是在ListView中去全選、多選、取消選擇選項,同時在ListView中我們常用ConvertView去優化效率,但是加入

CheckBox後,當我們選擇的item被滑動消失後又出現時,因為item複用的緣故,被選中的狀态可能消失,是以接下來我們主要的目的就是解決這個問題

1)單個list item布局list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
<TextView
    android:id="@+id/item_tv"
    android:text="資料一"
    android:layout_width="wrap_content"
    android:layout_alignBaseline="@id/checkbox"
    android:layout_height="wrap_content" />
 <CheckBox
    android:layout_alignParentRight="true"
     android:paddingRight="20dp"
     android:id="@+id/checkbox"
     android:clickable="false"
     android:focusable="false"
     android:focusableInTouchMode="false"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />


</RelativeLayout>           

2)主布局檔案chb_list_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.elimy.checkboxui.ChbListActivityActivity">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/selectAll"
            android:text="全選"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />
        <Button
            android:id="@+id/unSelect"
            android:text="取消選擇"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            />
    </LinearLayout>
    <ListView
        android:id="@+id/listview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">


    </ListView>
</LinearLayout>           

3)擴充卡類MyAdapter.java

package com.example.elimy.checkboxui;


import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


/**
 * Created by elimy on 2016-08-07.
 * 功能:實作資料與布局的綁定
 */
public class MyAdapter extends BaseAdapter {
    private ArrayList<String>  list =null;
    private Context context=null;
    private LayoutInflater inflater= null;
    private static HashMap<Integer,Boolean> checkeds=null;


    /*
    實作checkeds屬性的get set方法,友善在布局類中設定值
     */
    public HashMap<Integer, Boolean> getCheckeds() {
        return checkeds;
    }


    public void setCheckeds(HashMap<Integer, Boolean> checkeds) {
        MyAdapter.checkeds = checkeds;
    }


    /*
    * Context:上下文
    * ArrayList<Map<String,Object>>:
    * String []:顯示Map中的key數組
    * int[]:布局id的數組
    * */
    public MyAdapter(Context context,ArrayList<String> list) {
        this.list =list;
        this.context=context;
        this.inflater=LayoutInflater.from(context);
        //執行個體化checkbox狀态Map
        checkeds=new HashMap<Integer,Boolean>();
        for (int i=0;i<list.size();i++){
            getCheckeds().put(i, false);
        }
    }


    @Override
    public int getCount() {
        return list.size();
    }


    @Override
    public Object getItem(int position) {
        return list.get(position);
    }


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


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder =null;
        //如果ViewHolder為null則初始化
        //如果不為空就直接使用
        if(holder ==  null){
            holder =new ViewHolder();
            if(convertView == null){
                //inflate加載單個list item布局檔案
                convertView =inflater.inflate(R.layout.list_item,null);
            }
           //實作TextView初始化映射
            holder.tv= (TextView) convertView.findViewById(R.id.item_tv);
            //實作CheckBox初始化映射
            holder.ckb= (CheckBox) convertView.findViewById(R.id.checkbox);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        //設定textview顯示内容
        holder.tv.setText(list.get(position));
        //設定Checkbox的狀态
        holder.ckb.setChecked(getCheckeds().get(position));
        return convertView;


    }
    /*
    *ViewHolder封裝布局類的執行個體化映射
    * 首次實作初始化後會儲存映射關系,第二次初始化的
    * 可以複用,以此來達到提高效率的目的
     */
    class ViewHolder{
        private TextView tv;
        public CheckBox ckb;


    }
}           

4)主布局類ChbListActivityActivity.java

package com.example.elimy.checkboxui;


import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


import java.util.ArrayList;




public class ChbListActivityActivity extends AppCompatActivity {
    private ListView listView;
    private Button selectAll,unSelect;
    private ArrayList<String> data= null ;
    private CheckBox checkBox;
    private int checkedNum =0;
    private TextView item_tv;
    /**
     * list需要的資源:1.擴充卡adapter 2.listview 3.資料
     *
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chb_list_activity);
        //初始化
        selectAll = (Button) findViewById(R.id.selectAll);
        unSelect = (Button) findViewById(R.id.unSelect);
        checkBox = (CheckBox)findViewById(R.id.checkbox);
        item_tv = (TextView) findViewById(R.id.item_tv);
        //初始化listview
        listView = (ListView) findViewById(R.id.listview);


        //初始化資料
        final ArrayList<String> data = initData();
        //初始化擴充卡
         final MyAdapter myAdapter = new MyAdapter(ChbListActivityActivity.this,data);
        //為listView設定擴充卡
        listView.setAdapter(myAdapter);


        //selectAll設定監聽器
        selectAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (int i = 0; i < data.size(); i++) {
                    myAdapter.getCheckeds().put(i, true);
                }
                //資料改變通知
                myAdapter.notifyDataSetChanged();
            }
        });
        //unSelect取消監聽
        unSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for(int i=0; i<data.size();i++){
                    if (myAdapter.getCheckeds().get(i)==true) {
                        myAdapter.getCheckeds().put(i, false);
                    }
                }


                myAdapter.notifyDataSetChanged();
            }
        });
        //item點選事件監聽
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {


               // checkboxClick(myAdapter,position);


                //取得viewHolder執行個體,避免一層層的去找CheckBox
                MyAdapter.ViewHolder holder= (MyAdapter.ViewHolder) view.getTag();
                //更改CheckBox狀态
                holder.ckb.toggle();
                //記錄CheckBox狀态
                myAdapter.getCheckeds().put(position,holder.ckb.isChecked());
               //擷取單擊項的文本
                String s = data.get(position);
                if(holder.ckb.isChecked()==true){
                    Toast.makeText(ChbListActivityActivity.this,"你選了"+s,Toast.LENGTH_SHORT).show();
                }else {
                    Toast.makeText(ChbListActivityActivity.this,"你取消了選擇"+s,Toast.LENGTH_SHORT).show();
                }
                //資料改變通知
                myAdapter.notifyDataSetChanged();
            }
        });
    }
    /*
    *單擊事件的另一種處理方法
     */
    public void checkboxClick(MyAdapter myAdapter, int position){


        String s = data.get(position);
        Log.d("String","s");
        if (myAdapter.getCheckeds().get(position)==true) {
            myAdapter.getCheckeds().put(position, false);
            Toast.makeText(ChbListActivityActivity.this,"你取消了選擇"+s,Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(ChbListActivityActivity.this,"你選擇了"+s,Toast.LENGTH_SHORT).show();
            myAdapter.getCheckeds().put(position, true);
        }
        myAdapter.notifyDataSetChanged();


    }
    /*
    * 初始化資料
    */
    private ArrayList<String> initData() {
        data = new ArrayList<String>();
            //初始化TextView text數組
            for(int i=0;i<18;i++){
                data.add("資料" + i);
            }
        return data;
    }
}           

5)效果截圖

Android UI(CheckBox)詳解