1. 程式人生 > >比ListView還要叼的recycleview

比ListView還要叼的recycleview

RecycleView

關於RecycleView的介紹網上有很多,據說是谷歌為了解決ListView的某些問題和實現更多的功能在ListView的基礎開發出來的,可以實現瀑布流和左右滑動以及上下滑動,相關方法再網上都可以找到,這裡只寫本人用到的功能,單純只是為了總結知識

使用

匯入包

implementation "com.android.support:recyclerview-v7:25.3.1"

程式碼中呼叫

 LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        //設定RecyclerView 佈局
        recyclerView.setLayoutManager(layoutManager);
        //設定Adapter
        MyTopicAdapter adapter = new MyTopicAdapter(topicsBean,"F");
        recyclerView.setAdapter(adapter);

其中MyTopicAdapter程式碼如下:

package adapter;

import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;

import com.example.donview.campusspirit.R;

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

import topics.TopicsBean;
import viewholder.BaseViewHolder;


/**
 * Created by Donview on 2018/8/16.
 */

public class MyTopicAdapter extends RecyclerView.Adapter<BaseViewHolder> {
    private static TopicsBean topicsBean;
    private static TopicsBean topicsEBean;
    public static Map<Integer, Boolean> isSelected=new HashMap<>();
    public static Map<Integer, Boolean> isESelected=new HashMap<>();
    protected int size=2;
    private int count=0;
    protected BaseViewHolder holder;
    protected String type;

    public MyTopicAdapter(TopicsBean topicsBean, String type){
        switch (type){
            case "F":
                this.topicsBean=topicsBean;
                count=topicsBean.getOptionCount();
                initSelected(topicsBean.getOptionCount(),"F");
                break;
            case "E":
                this.topicsEBean=topicsBean;
                count=topicsEBean.getOptionCount();
                map=new HashMap<>();
                initSelected(topicsBean.getOptionCount(),"E");
                break;
        }
        this.type=type;
    }
    //建立時自動呼叫
    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (type){
            case "F":
                inflaterFView(parent);
                break;
            case "E":
                inflaterEView(parent);
                break;
        }
        return holder;
    }
    //關聯ViewHolder
    @Override
    public void onBindViewHolder(BaseViewHolder viewHolder, int position) {
        //設定選項內容
        switch (type){
            case "F":
                bindFView(viewHolder,position);
                break;
            case "E":
                bindEView(viewHolder,position);
                break;
        }
    }
    //解析F題型的佈局檔案
    private void inflaterFView(ViewGroup parent) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type2_option,parent,false);
        holder = new BaseViewHolder(view,"F");
    }
    //賦值F題型
    private void bindFView(BaseViewHolder viewHolder, int position) {
        if (position<topicsBean.getOptionCount()){
            viewHolder.cb_optionA.setVisibility(View.VISIBLE);
            viewHolder.tv_content1.setVisibility(View.VISIBLE);
            viewHolder.cb_optionA.setText(topicsBean.getOptionList().get(position));
            viewHolder.tv_content1.setText(topicsBean.getAnswerList().get(position));
        }else {
            viewHolder.cb_optionA.setVisibility(View.GONE);
            viewHolder.tv_content1.setVisibility(View.GONE);
        }
        initOption(position,viewHolder);
    }
    //解析E題型的佈局檔案
    private void inflaterEView(ViewGroup parent) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type3_option,parent,false);
        holder = new BaseViewHolder(view,"E");
    }
    //賦值E題型
    private void bindEView(BaseViewHolder viewHolder, int position) {
        if (position<topicsEBean.getOptionCount()){
            viewHolder.cb_optionA.setVisibility(View.VISIBLE);
            viewHolder.tv_content1.setVisibility(View.VISIBLE);
            viewHolder.cb_optionA.setOnCheckedChangeListener(new MyOnCheckedListener(position));
            viewHolder.tv_content1.setText(topicsEBean.getAnswerList().get(position));
        }else {
            viewHolder.cb_optionA.setVisibility(View.GONE);
            viewHolder.tv_content1.setVisibility(View.GONE);
        }
        initOption(position,viewHolder);
    }
    @Override
    public int getItemCount() {
        return  count;
    }
    //設定選擇題ListView中CheckBox的文字與選中狀態
    protected void initOption(final int position, final BaseViewHolder viewHolder) {
        final int type = this.type=="F"?topicsBean.getType():topicsEBean.getType();
        final Map<Integer, Boolean> select=this.type=="F"?isSelected:isESelected;
        if ( position < size) {
            viewHolder.cb_optionA.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (select.get(position) == false) {
                        select.put(position, true);
                        //type==1?單選:不定項
                        if (type==1){
                            unSelect(position);
                            notifyDataSetChanged();
                        }
                    } else {
                        select.put(position, false);
                    }
                }
            });
            viewHolder.cb_optionA.setChecked(select.get(position));
        }
    }
    //初始化checkbox的選中狀態
    public void initSelected(int size,String typeName) {
        this.size=size;
        Map<Integer, Boolean> selected=typeName=="F"?isSelected:isESelected;
        for (int i = 0; i < size; i++) {
            selected.put(i, false);
            if (typeName=="E")
                map.put(i," ");
        }
    }
    //取消當前選項以外所有選項選中
    private void unSelect(int position) {
        for (int i=0;i<size;i++){
            if (i!=position){
                if (type=="F")
                    isSelected.put(i, false);
                else isESelected.put(i,false);
            }
        }
    }
    //1.檢視F題型是否有選中選項
    public static boolean hasCheck() {
        for (int i=0;i<isSelected.size();i++){
            if (isSelected.get(i)==true)
                return true;
        }
        return false;
    }
    //檢視E題型是否全選
    public static boolean hasEChecked() {
        for (int i=0;i<map.size();i++){
            if (!map.get(i).equalsIgnoreCase("√")&&!map.get(i).equalsIgnoreCase("╳")){
                Log.i("MyCommitTopic","CommitTopic:map.get(i)="+map.get(i));
                return false;
            }
        }
        return true;
    }
    //2.返回F題型選中選項
    public static String getCheck() {
        String result="";
        for (int i=0;i<isSelected.size();i++){
            if (isSelected.get(i)==true){
                result+=topicsBean.getOptionList().get(i)+",";
            }
        }
        result=result.substring(0,result.length()-1);
        return result;
    }
    //返回E題型選中選項
    public static String getCheckE() {
        String result="";
        for (int i=0;i<map.size();i++){
            if (map.get(i).equalsIgnoreCase("√")){
                result+=topicsBean.getOptionList().get(i)+",";
            }
        }
        if (result.length()>=1)
        result=result.substring(0,result.length()-1);
        return result;
    }
    private static Map<Integer,String> map;
    //E題型的選中事件
    private class MyOnCheckedListener implements CompoundButton.OnCheckedChangeListener {
        int position=0;
        public MyOnCheckedListener(int position) {
            this.position=position;
        }
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            buttonView.setText(isChecked?"√":"╳");
            map.put(position,isChecked?"√":"╳");
        }
    }
}

自身就可以封裝自定義的ViewHolder比ListView方便很多而且簡潔得多:

package viewholder;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.donview.campusspirit.R;

/**
 * Created by Donview on 2018/8/17.
 */

public class BaseViewHolder extends RecyclerView.ViewHolder{
    public TextView tv_className;
    public TextView tv_teacherName;
    public TextView tv_topicName;
    public TextView tv_date;
    public TextView tv_time;
    public LinearLayout ll_work_content;
    public CheckBox cb_optionA;
    public TextView tv_content1;
    public BaseViewHolder(View itemView, String type) {
        super(itemView);
        switch (type){
            case "F":
                findViewFromF(itemView);
                break;
            case "E":
                findViewFromE(itemView);
                break;
            case "Work":
                findViewFromWork(itemView);
                break;
        }
    }
    //F題型配置
    private void findViewFromF(View itemView) {
        cb_optionA= (CheckBox) itemView.findViewById(R.id.cbf_optionA);
        tv_content1=(TextView)itemView.findViewById(R.id.tvf_content1);
    }
    //E題型配置
    private void findViewFromE(View itemView) {
        cb_optionA= (CheckBox) itemView.findViewById(R.id.cbe_optionA);
        tv_content1=(TextView)itemView.findViewById(R.id.tve_content1);
    }
    //WorkPage配置
    private void findViewFromWork(View itemView) {
        ll_work_content=(LinearLayout)itemView.findViewById(R.id.ll_work_content);
        tv_className= (TextView) itemView.findViewById(R.id.tv_work_className);
        tv_teacherName= (TextView) itemView.findViewById(R.id.tv_work_teacherName);
        tv_topicName= (TextView) itemView.findViewById(R.id.tv_work_topicName);
        tv_date= (TextView) itemView.findViewById(R.id.tv_work_date);
        tv_time= (TextView) itemView.findViewById(R.id.tv_work_time);
    }
}

RecycleView本身不實現點選事件,需要自己實現,方法多種,這裡給出在Adapter裡面實現介面的方法

package adapter;

import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.donview.campusspirit.R;

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

import viewholder.BaseViewHolder;

/**
 * Created by Donview on 2018/8/21.
 */

public class MyWorkAdapter extends RecyclerView.Adapter<BaseViewHolder> implements View.OnClickListener{
    private ArrayList<Map> arrayList;
    protected BaseViewHolder holder;
    public MyWorkAdapter(ArrayList<Map> arrayList){
        this.arrayList=arrayList;
    }
    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_work_pager,parent,false);
        view.setOnClickListener(this);
        holder = new BaseViewHolder(view,"Work");
        return holder;
    }

    @Override
    public void onBindViewHolder(BaseViewHolder viewHolder, int position) {
        if (position>arrayList.size()) return;
        viewHolder.tv_className.setText(arrayList.get(position).get("class_name").toString());
        viewHolder.tv_teacherName.setText(arrayList.get(position).get("realName").toString());
        viewHolder.tv_topicName.setText(arrayList.get(position).get("task_name").toString());
        viewHolder.tv_date.setText(arrayList.get(position).get("date").toString());
        viewHolder.tv_time.setText(arrayList.get(position).get("time").toString());
        viewHolder.itemView.setTag(position);
        int color=arrayList.get(position).get("all_done").toString().equalsIgnoreCase("1")?
                 android.graphics.Color.parseColor("#AAAAAA")
                :android.graphics.Color.parseColor("#ff33b5e5");
        Log.i("UserAccount","Work:position"+position+",all_done="+arrayList.get(position).get("all_done").toString());
        viewHolder.ll_work_content.setBackgroundColor(color);
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    private OnItemClickListener mOnItemClickListener = null;

    @Override
    public void onClick(View v) {
        if (mOnItemClickListener != null) {
            //注意這裡使用getTag方法獲取position
            mOnItemClickListener.onItemClick(v,(int)v.getTag());
        }
    }

    public static interface OnItemClickListener {
        void onItemClick(View view , int position);
    }
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }
}

然後程式碼中呼叫:

 //RecycleView選項監聽
    private class MyWorkOnItemClickListener implements MyWorkAdapter.OnItemClickListener {
        @Override
        public void onItemClick(View view, int position) {
            if (position>arrayList.size()){
                Log.i("FoolException","IndexOutOfBoundsException!WorkPage陣列下標超出了");
                return;
            }
            MyApplication.setTask_id((int)arrayList.get(position).get("task_id"));
            Log.i("TestViewHolder","Click:task_id="+ MyApplication.getTask_id()+
                    ",userId="+ MyApplication.getUserId()+",userName="+
                    MyApplication.getUserName()+",task_name="+arrayList.get(position).get("task_name")+",all_done="+
                    arrayList.get(position).get("all_done"));
            context.startActivity(new Intent(context, TopicListActivity.class));
        }
    }