Android中RecyclerView在TV中处理控件焦点移动,EditText值的修改,CheckBox复用等问题解决

来源:互联网 发布:dsp算法大全c语言 pdf 编辑:程序博客网 时间:2024/06/05 08:31

编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/74990099

前言

  这篇博客是 :Android中RecyclerView的item中控件的点击事件添加删除一行、上移下移一行的代码实现 的后续篇。主要是讲RecyclerView在TV中控件焦点移动的处理以及RecyclerView的item中包含 EditText和CheckBox控件的处理逻辑

Demo展示图片

这里写图片描述

布局代码

// (layout)activity_main.xml<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=".MainActivity">    <android.support.v7.widget.RecyclerView        android:id="@+id/recyclerview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:overScrollMode="never"        android:scrollbars="none"/></RelativeLayout>----------------------------------------------------------------------------------------// (layout)recyclerview_item.xml<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="wrap_content"              android:background="@drawable/recyclerview_bg">    <TextView        android:id="@+id/num"        android:layout_width="25dp"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:gravity="center"        android:textSize="20sp"        android:layout_margin="10dp"        android:textColor="#fff"/>    <EditText        android:id="@+id/data"        android:layout_toRightOf="@+id/num"        android:layout_marginTop="10dp"        android:layout_marginBottom="10dp"        android:layout_marginLeft="4dp"        android:layout_width="50dp"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:padding="5dp"        android:gravity="center"        android:background="@drawable/edittext_selector"        android:textSize="20sp"        android:textColor="@color/colorAccent"/>    <CheckBox        android:id="@+id/isForsale"        android:layout_toRightOf="@+id/data"        android:layout_centerVertical="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="11dp"        android:focusable="true"        android:button="@drawable/checkbox_selector"/>    <LinearLayout        android:id="@+id/ll"        android:layout_alignParentRight="true"        android:layout_centerVertical="true"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:orientation="horizontal">        <Button            android:id="@+id/add"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="添加"            android:textSize="20sp"            android:layout_margin="5dp"            android:minHeight="0dp"            android:minWidth="0dp"            android:padding="5dp"            android:background="@drawable/button_selector"            android:clickable="true"            android:textColor="@color/colorAccent"/>        <Button            android:id="@+id/del"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="删除"            android:textSize="20sp"            android:layout_margin="5dp"            android:minHeight="0dp"            android:minWidth="0dp"            android:padding="5dp"            android:background="@drawable/button_selector"            android:clickable="true"            android:textColor="@color/colorAccent"/>        <Button            android:id="@+id/up"            android:layout_width="35dp"            android:layout_height="wrap_content"            android:text="↑"            android:textSize="20sp"            android:gravity="center"            android:layout_margin="5dp"            android:minHeight="0dp"            android:minWidth="0dp"            android:padding="5dp"            android:background="@drawable/button_selector"            android:clickable="true"            android:textColor="@color/colorAccent"/>        <Button            android:id="@+id/down"            android:layout_width="35dp"            android:layout_height="wrap_content"            android:text="↓"            android:textSize="20sp"            android:gravity="center"            android:layout_margin="5dp"            android:minHeight="0dp"            android:minWidth="0dp"            android:padding="5dp"            android:background="@drawable/button_selector"            android:clickable="true"            android:textColor="@color/colorAccent"/>    </LinearLayout></RelativeLayout>----------------------------------------------------------------------------------------// (layout)button_selector.xml<selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true" android:drawable="@drawable/shape_yellow"/>    <item android:state_focused="true" android:drawable="@drawable/shape_yellow"/>    <item android:drawable="@drawable/shape_normal"/></selector>----------------------------------------------------------------------------------------// (layout)checkbox_selector.xml<selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@drawable/checkbox_checked" android:state_checked="true" />    <item android:drawable="@drawable/checkbox_focus" android:state_focused="true" />    <item android:drawable="@drawable/checkbox_normal"/></selector>----------------------------------------------------------------------------------------// (layout)edittext_selector.xml<selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_pressed="true" android:drawable="@drawable/shape_yellow"/>    <item android:state_focused="true" android:drawable="@drawable/shape_yellow"/>    <item android:drawable="@drawable/shape_normal"/></selector>----------------------------------------------------------------------------------------// (layout)recyclerview_bg.xml<selector xmlns:android="http://schemas.android.com/apk/res/android">    <item>        <shape android:shape="rectangle">            <solid android:color="@color/colorAccent"/>            <stroke android:width="1dp" android:color="@color/colorPrimaryDark"/>        </shape>    </item></selector>----------------------------------------------------------------------------------------// (layout)shape_yellow.xml<shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#D8E033"/>    <corners android:radius="4dp"/>    <stroke android:color="#2BA6E1"            android:width="1dp"/></shape>

逻辑代码

// MainActivityimport android.content.Context;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.Log;import android.view.View;import android.view.WindowManager;import android.widget.Toast;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import java.util.List;public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    private RecyclerView mRecyclerView;    private Context mContext = MainActivity.this;    private MyAdapter mMyAdapter;    private int clickTime = 0;    private List<PriceBean> mList;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 解决一进入Activity就自动弹出虚拟键盘问题        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);        setContentView(R.layout.activity_main);        initView();        initData();    }    private void initView() {        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);    }    public void initData(){        String jsonArr = "[\n" +                "  {\n" +                "      \"id\": \"250\",\n" +                "      \"name\": \"鲢鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"629\",\n" +                "      \"name\": \"鳙鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"603\",\n" +                "      \"name\": \"草鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"180\",\n" +                "      \"name\": \"鲤鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"138\",\n" +                "      \"name\": \"鲫鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"631\",\n" +                "      \"name\": \"河蟹\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"685\",\n" +                "      \"name\": \"带鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"142\",\n" +                "      \"name\": \"鲳鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"136\",\n" +                "      \"name\": \"鲈鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"181\",\n" +                "      \"name\": \"白鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"957\",\n" +                "      \"name\": \"白鲢\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"359\",\n" +                "      \"name\": \"墨鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"133\",\n" +                "      \"name\": \"鳊鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"231\",\n" +                "      \"name\": \"泥鳅\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"137\",\n" +                "      \"name\": \"黄鳝\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"131\",\n" +                "      \"name\": \"黑鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  \n" +                "  {\n" +                "      \"id\": \"009\",\n" +                "      \"name\": \"银鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"050\",\n" +                "      \"name\": \"刀鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"001\",\n" +                "      \"name\": \"河豚\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  },\n" +                "  {\n" +                "      \"id\": \"100\",\n" +                "      \"name\": \"鳇鱼\",\n" +                "      \"is_forsale\": \"0\"\n" +                "  }\n" +                "]";        Gson gson = new Gson();        mList = gson.fromJson( jsonArr , new TypeToken<List<PriceBean>>(){}.getType());        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);        mRecyclerView.setLayoutManager(linearLayoutManager);        mMyAdapter = new MyAdapter(mList);        // 设置item及item中控件的点击事件        mMyAdapter.setOnItemClickListener(onItemClickListener);        mRecyclerView.setAdapter(mMyAdapter);    }    /**     * Item点击监听。     */    private OnItemClickListener onItemClickListener = new OnItemClickListener() {        @Override        public void onItemClick(int position , View v) {            switch (v.getId()){                case R.id.add:                    clickTime++;                    Toast.makeText(mContext , "增:" + position, Toast.LENGTH_SHORT).show();                    // 添加一条空数据,并设置id为0,不特价                    PriceBean priceBean = new PriceBean();                    priceBean.setId("0");                    priceBean.setIs_forsale("0");                    priceBean.setName("");                    mList.add(position + 1 , priceBean);                    mMyAdapter.notifyDataSetChanged();                    Log.i(TAG , "mStrList:" + mList.toString());                    break;                case R.id.del:                    Toast.makeText(mContext, "删:" + position, Toast.LENGTH_SHORT).show();                    mList.remove(position);                    mMyAdapter.notifyDataSetChanged();                    break;                case R.id.up:                    if(position == 0){                        Toast.makeText(mContext, "已经在顶部,无法移动!:" + position, Toast.LENGTH_SHORT).show();                    }else if(position > 0 && position <= mList.size()-1){                        Toast.makeText(mContext, "上:" + position, Toast.LENGTH_SHORT).show();                        swap(mList , position , position-1);                        mMyAdapter.notifyDataSetChanged();                    }                    break;                case R.id.down:                    if(position == mList.size()-1){                        Toast.makeText(mContext, "已经在底部,无法移动!:" + position, Toast.LENGTH_SHORT).show();                    }else if(position >= 0 && position < mList.size()-1){                        Toast.makeText(mContext, "下:" + position, Toast.LENGTH_SHORT).show();                        swap(mList , position , position+1);                        mMyAdapter.notifyDataSetChanged();                    }                    break;            }        }    };    /**     * 集合中两个元素的交换操作     * @param list     * @param oldPosition     * @param newPosition     * @param <T>     */    public static <T> void swap(List<T> list, int oldPosition, int newPosition){        if(null == list){            throw new IllegalStateException("The list can not be empty...");        }        T tempElement = list.get(oldPosition);        // 向前移动,前面的元素需要向后移动        if(oldPosition < newPosition){            for(int i = oldPosition; i < newPosition; i++){                list.set(i, list.get(i + 1));            }            list.set(newPosition, tempElement);        }        // 向后移动,后面的元素需要向前移动        if(oldPosition > newPosition){            for(int i = oldPosition; i > newPosition; i--){                list.set(i, list.get(i - 1));            }            list.set(newPosition, tempElement);        }    }}----------------------------------------------------------------------------------------// MyAdapterimport android.support.v7.widget.RecyclerView;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.EditText;import android.widget.TextView;import com.yanzhenjie.recyclerview.swipe.SwipeMenuAdapter;import java.util.List;public class MyAdapter extends SwipeMenuAdapter<MyAdapter.MyViewHolder> {    private static final String TAG = "MyAdapter";    private List<PriceBean> list;    private OnItemClickListener mOnItemClickListener;    public MyAdapter(List<PriceBean> mList){        this.list = mList;    }    public void setOnItemClickListener(OnItemClickListener onItemClickListener){        this.mOnItemClickListener = onItemClickListener;    }    @Override    public View onCreateContentView(ViewGroup parent, int viewType) {        return LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);    }    @Override    public MyAdapter.MyViewHolder onCompatCreateViewHolder(View realContentView, int viewType) {        MyViewHolder myViewHolder = new MyViewHolder(realContentView);        myViewHolder.mOnItemClickListener = mOnItemClickListener;        return myViewHolder;    }    @Override    public void onBindViewHolder(final MyAdapter.MyViewHolder holder, final int position) {        // 取消条目复用 不取消复用CheckBox会有复用问题        holder.setIsRecyclable(false);        holder.num.setText((position + 1) + "");        holder.data.setText(list.get(position).getName());        // 如果is_forsale为0,设置为不特价,如果is_forsale为1,设置为特价        if(list.get(position).getIs_forsale().equals("0")){            holder.isForsale.setChecked(false);            Log.i(TAG, list.get(position).getName() + "不特价!");        }else if(list.get(position).getIs_forsale().equals("1")){            holder.isForsale.setChecked(true);            Log.i(TAG, list.get(position).getName() + "特价!");        }        holder.data.setOnFocusChangeListener(new View.OnFocusChangeListener() {            @Override            public void onFocusChange(View v, boolean hasFocus) {                if(!hasFocus){                    Log.i(TAG, "EditText失去焦点");                    // list中保存的是我焦点在EditText上移动后从EditText中获取的值                    list.get(position).setName(holder.data.getText().toString().trim());                    // EditText每失去一次焦点,就在list中保存一次                    Log.i(TAG , "list" + list);                }            }        });        holder.isForsale.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {            @Override            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {                if (isChecked) {                    // 选中的同时获取焦点                    holder.isForsale.setFocusableInTouchMode(true);                    holder.isForsale.requestFocus();                } else {                    Log.i(TAG, "CheckBox取消选中");                }            }        });        holder.isForsale.setOnFocusChangeListener(new View.OnFocusChangeListener() {            @Override            public void onFocusChange(View v, boolean hasFocus) {                if (!hasFocus) {                    // CheckBox每失去一次焦点,就在list中保存一次                    Log.i(TAG, "CheckBox失去焦点");                    if (holder.isForsale.isChecked()) {                        list.get(position).setIs_forsale("1");                    } else {                        list.get(position).setIs_forsale("0");                    }                    Log.i(TAG , "list" + list);                }            }        });    }    @Override    public int getItemCount() {        return list == null ? 0 : list.size();    }    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {        OnItemClickListener mOnItemClickListener;        TextView num;        EditText data;        CheckBox isForsale;        TextView add;        TextView del;        TextView up;        TextView down;        MyViewHolder(View itemView) {            super(itemView);            num = (TextView) itemView.findViewById(R.id.num);            data = (EditText) itemView.findViewById(R.id.data);            isForsale = (CheckBox)itemView.findViewById(R.id.isForsale);            add = (TextView) itemView.findViewById(R.id.add);            del = (TextView) itemView.findViewById(R.id.del);            up = (TextView) itemView.findViewById(R.id.up);            down = (TextView) itemView.findViewById(R.id.down);            add.setOnClickListener(this);            del.setOnClickListener(this);            up.setOnClickListener(this);            down.setOnClickListener(this);        }        @Override        public void onClick(View v) {            if (mOnItemClickListener != null) {                mOnItemClickListener.onItemClick(getAdapterPosition() , v);            }        }    }}----------------------------------------------------------------------------------------// OnItemClickListenerimport android.view.View;public interface OnItemClickListener {    void onItemClick(int position, View v);}----------------------------------------------------------------------------------------// PriceBeanpublic class PriceBean {    private String id;    private String name;    private String is_forsale;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getIs_forsale() {        return is_forsale;    }    public void setIs_forsale(String is_forsale) {        this.is_forsale = is_forsale;    }    @Override    public String toString() {        return "PriceBean{" +                "id='" + id + '\'' +                ", name='" + name + '\'' +                ", is_forsale='" + is_forsale + '\'' +                '}';    }}

注:

  需要在project的build.gradle中添加:

compile 'com.yanzhenjie:recyclerview-swipe:1.0.4'compile 'com.google.code.gson:gson:2.4'

Demo下载请移步:http://download.csdn.net/detail/zxc514257857/9895519


———-因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!———-

阅读全文
0 0