Android控件与布局——基础控件CheckedTextView

        最近在用原生的控件和布局绘制一些界面并使用,虽然这些都是Android基本知识,但是有的时候真的感觉力不从心,感觉有必要对Android常用的控件和布局做一个系统的了解。后续一个月甚至更多的时间都会围绕这个主题展开,毕竟这里面还是有不少高级控件的,我也会尽量结合应用深入的进行了解。

项目GitHub地址入口

上一篇:RadioButton     下一篇:Spinner

今天,我们的主题是CheckedTextView,它是一种对TextView进行了扩展的控件,下面看一下官方文档的介绍:

* An extension to {@link TextView} that supports the {@link Checkable}
* interface and displays.
* 

* This is useful when used in a {@link android.widget.ListView ListView} where * the {@link android.widget.ListView#setChoiceMode(int) setChoiceMode} has * been set to something other than * {@link android.widget.ListView#CHOICE_MODE_NONE CHOICE_MODE_NONE}.

可见,其通常配合ListView实现单选或者多选的操作,后面我们会结合ListView进行简单的演示。上面说到,这是一个继承至TextView且实现了Checkable接口的控件,下面看看其基本的使用和展示:

   

和一个TextView没有任何区别,下面,我们给上面的控件添加一个属性android:checkMark:



    

    

Android控件与布局——基础控件CheckedTextView_第1张图片

可见,通过这个属性可以为CheckedTextView添加一个图标,至于TextView的设置文本相关的属性这里就不在演示了。此外,我们看到这个控件像是一个TextView与一个ImageView的组合,很像一个简单ListView的Item布局,当然这不是上面文档说其适合配合ListView的原因,之所以说其常常配合ListView使用是因为其实现了Checkable接口且ListView中有setItemCheck()这样的接口。下面是setItemCheck()的描述:

/**
 * Sets the checked state of the specified position. The is only valid if
 * the choice mode has been set to {@link #CHOICE_MODE_SINGLE} or
 * {@link #CHOICE_MODE_MULTIPLE}.
 *
 * @param position The item whose checked state is to be checked
 * @param value The new checked state for the item
 */

设置ListView对应position上的item的状态为checked,且只有在ListView设置为CHOICE_MODE_SINGLE和CHOICE_MODE_MULTIPLE下有效,这里这两个常参表示单选或者多选的意思。所以这也是常常使用ListView配合CheckedTextView实现单选或者多选的原因,此外,我们也可以通过上文关于RadioButton介绍中说的,使用RadioButtom配合RadioGroup实现,但是,后者只能针对定长的选项可以,对于选项数量可变的不好实现,而前者恰恰弥补了这一点。

下面就来通过ListView配合CheckedTextView实现一下多选的效果(不是通过上述方式),示例的运行结果如下:

Android控件与布局——基础控件CheckedTextView_第2张图片

主要的逻辑代码有我们的适配器MyAdaptor.java代码

package aoto.com.commonwidgetandlayout.basic_widget.checkedTextView;

import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import java.util.ArrayList;

import java.util.List;

import aoto.com.commonwidgetandlayout.R;

/**
 * author:why
 * created on: 2019/5/14 10:49
 * description:
 */
public class MyAdaptor extends ArrayAdapter {
    private static final String TAG = "MyAdaptorWhy";
    private int resourceID;
    private Context context;
    private ArrayList resultList;
    public MyAdaptor(@NonNull Context context, int resource, List list) {
        super(context, resource,list);
        this.context = context;
        this.resourceID = resource;
        resultList=new ArrayList();
    }

    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        View view;
        final ViewHolder holder;
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceID, parent, false);
            holder=new ViewHolder();
            holder.checkedTextView=view.findViewById(R.id.checked_textView);
            view.setTag(holder);
        } else {
            //布局缓存处理
            view = convertView;
            holder = (ViewHolder) view.getTag();
        }

        String str = getItem(position);
        holder.checkedTextView.setText(str);
        holder.checkedTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                holder.checkedTextView.toggle();//切换选中与非选中状态
                if(holder.checkedTextView.isChecked()){
                    resultList.add(holder.checkedTextView.getText().toString());
                }
                else {
                    if(resultList.contains(holder.checkedTextView.getText().toString())){
                        resultList.remove(holder.checkedTextView.getText().toString());
                    }
                }
            }
        });
        return view;
    }

    class ViewHolder {
       CheckedTextView checkedTextView;
    }


    public ArrayList getList(){
        return resultList;
    }
}

控制层代码CTextViewActivity.java代码:

package aoto.com.commonwidgetandlayout.basic_widget.checkedTextView;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;

import aoto.com.commonwidgetandlayout.R;

/**
 * @author why
 * @date 2019-5-14 10:07:30
 */
public class CTextViewActivity extends AppCompatActivity {

    private static final String TAG = "CTextViewActivityWhy";
    CheckedTextView textView;
    ListView listView;
    TextView chooseResult;
    MyAdaptor adaptor;
    ArrayList nameList=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ctext_view);
        chooseResult=findViewById(R.id.choose_result);
        listView=findViewById(R.id.name_list_view);
        nameList.add("苹果");
        nameList.add("香蕉");
        nameList.add("菠萝");
        nameList.add("西瓜");
        nameList.add("火龙果");
        adaptor=new MyAdaptor(this,R.layout.list_item,nameList);
        listView.setAdapter(adaptor);
    }

    public void confirm(View view){
        if(adaptor.getList().size()==0){
            chooseResult.setText("");
        }
        else {
            chooseResult.setText(adaptor.getList().toString());
        }
    }
}

主布局以及ListView子布局很简单,这里就直接给出了




    
    
    
    
        



    

这里很多都是关于ListView的知识,唯一用到的CheckedTextView的API就是toggle(),难得用到,我们就把它的源码拿出来看一下吧:

 public void toggle() {
        setChecked(!mChecked);
    }

超级简单,就是实现这个控件的状态置反操作。关于这个示例的细节就不解释,毕竟还是很简单的。这里我们ListView的子条目布局是一个LinearLayout中放置了一个CheckedTextView实现的。这个时候我们对ListView设置:

  listView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                
            }

            @Override
            public void onNothingSelected(AdapterView parent) {

            }
        });

在实际的操作中,我们是获取不到这个事件的,原因很简单,这个监听针对的是ListView子布局View实现了Checkable接口的。我们在上面实际上做了一个错误的示范,因为布局中就一个View,我们为什么不直接用CheckedTextView做ListView子项了,并且其还实现Chackable接口,配合ListView的API就可以实现单选或者多选的操作了。下面我们就按照这个思路来实现一下:

  • 第一步,更换适配器代码
package aoto.com.commonwidgetandlayout.basic_widget.checkedTextView;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;

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

import aoto.com.commonwidgetandlayout.R;

/**
 * author:why
 * created on: 2019/5/14 16:58
 * description:
 */
public class MyAdaptorTest extends ArrayAdapter {

    private static final String TAG = "MyAdaptorWhy";
    private Context context;
    private ArrayList resultList;
    public MyAdaptorTest(@NonNull Context context, int resource, List list) {
        super(context, resource,list);
        this.context = context;
        resultList=new ArrayList();
    }

    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        View view;
        final ViewHolder holder;
        if (convertView == null) {
            view = new CheckedTextView(context);
            holder=new ViewHolder();
            holder.checkedTextView= (CheckedTextView) view;
            view.setTag(holder);
        } else {
            //布局缓存处理
            view = convertView;
            holder = (ViewHolder) view.getTag();
        }
        String str = getItem(position);
        holder.checkedTextView.setText(str);
        holder.checkedTextView.setCheckMarkDrawable(R.drawable.checked_text_view_back);
        holder.checkedTextView.setTextSize(25);
        return view;
    }

    class ViewHolder {
        CheckedTextView checkedTextView;
    }

    public ArrayList getList(){
        return resultList;
    }
}
  • 第二步,更换控制层代码
package aoto.com.commonwidgetandlayout.basic_widget.checkedTextView;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.TextView;

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

import aoto.com.commonwidgetandlayout.R;

/**
 * @author why
 * @date 2019-5-14 15:05:23
 */
public class CTextViewTestActivity extends AppCompatActivity {

    private static final String TAG = "CTextViewActivityWhy";
    CheckedTextView textView;
    ListView listView;
    TextView chooseResult;
    MyAdaptorTest adaptor;
    List record = new ArrayList();
    ArrayList nameList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.checked_text_view_test);
        chooseResult = findViewById(R.id.choose_result);
        listView = findViewById(R.id.name_list_view);
        nameList.add("苹果");
        nameList.add("香蕉");
        nameList.add("菠萝");
        nameList.add("西瓜");
        nameList.add("火龙果");
        adaptor = new MyAdaptorTest(this, 0, nameList);
        listView.setAdapter(adaptor);
        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        //listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                chooseResult.setText(nameList.get(position));//单选显示

                //多选显示
//                if (record.contains(nameList.get(position))) {
//                    record.remove(nameList.get(position));
//                } else {
//                    record.add(nameList.get(position));
//                }
//
//                if (record.size() == 0) {
//                    chooseResult.setText("");
//                } else {
//                    chooseResult.setText(record.toString());
//                }
            }
        });
    }
}

(1)我们首先在自定义适配器中的getView方法中直接返回一个CheckedTextView实例

(2)然后在调用ListView的setChoiceMode()设置选择模式

/**
 * Defines the choice behavior for the List. By default, Lists do not have any choice behavior
 * ({@link #CHOICE_MODE_NONE}). By setting the choiceMode to {@link #CHOICE_MODE_SINGLE}, the
 * List allows up to one item to  be in a chosen state. By setting the choiceMode to
 * {@link #CHOICE_MODE_MULTIPLE}, the list allows any number of items to be chosen.
 *
 * @param choiceMode One of {@link #CHOICE_MODE_NONE}, {@link #CHOICE_MODE_SINGLE}, or
 * {@link #CHOICE_MODE_MULTIPLE}
 */

(3)设置AdapterView.OnItemClickListener实现子项选择监听事件获取数据

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                chooseResult.setText(nameList.get(position));//单选显示
            }
        });

单选和多选的运行结果如下所示:

Android控件与布局——基础控件CheckedTextView_第3张图片

Android控件与布局——基础控件CheckedTextView_第4张图片

可见,使用CheckedTextView配合ListView实现单选与多选的功能我们实现了。好了,到这里,关于CheckedTextView我们也就介绍完了。

上一篇:RadioButton     下一篇:Spinner

注:欢迎扫码关注

 

你可能感兴趣的:(Android基础,随笔,Android,基础控件与布局使用介绍)