RecylerView(GridView布局)实现充值界面效果

来源:互联网 发布:主角可以优化功法的 编辑:程序博客网 时间:2024/05/22 06:33

RecylerView(GridView布局)实现充值界面效果

项目中有一个充值的效果如下:
效果图
之前为了赶项目进度,也没有多想,这不是很简单的么?5个TextView加1个EditText不就搞定了么?
的确这样做是可以实现的,而且也在规定时间内完成了项目。(但是存在局限性)
由于项目中多次的使用了RecycleView,然后发现这个用RecycleView实现效果会更好(布局更灵活,不限制个数),完成后的效果:
有角标
无角标

  • 1、数据传递效果的展示
    首先分析下这个界面需要的数据,由于这个界面是后台通过两个字段判断实现的效果
   String data = "3,9,30,50,100";   //isDiscount :1、有角标 2、无角标    String isDiscount = "1";

我们首先要通过IsDiscount这个字段来判断是否显示带角标的控件,以及data字段来判断动态添加几个控件

  • 2、界面实现效果分析
    1、组件选择
    文章开始就说到了,我们选用的是RecycleView这个控件结合GridView布局实现效果
    2、RecyeView Adapter布局分析
    ①有角标TextView
    ②正常无角标TextView
    ③EditText输入框
    布局如上三种,大家都知道RecycleView的强大,现在我们就利用它其中的ItemType这个功能,RecyleView很多复杂的界面都是通过ItemType这个属性来实现的。
    3、具体代码的实现
    ①ItemType种类的控制
 @Override public DemoAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {     switch (viewType) {       case ItemModel.ONE:                ///左上角三角标识布局;                return new CornorViewHoler(LayoutInflater.from(parent.getContext()).inflate(R.layout.corner_one, parent, false));     case ItemModel.TWO:                return new OneViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.one, parent, false));      case ItemModel.THREE:                return new TWoViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.two, parent, false));        }        return null;    }

在onCreateViewHolde这个方法中添加所需要的三种布局文件
②Item数据封装
在这个Adapter中,由于我需要知道几个条件,第一个是当前选中的状态是否是免费的标志,第二个是当前选中的值,所以封装了一个ItemModel的类用于处理数据

public class ItemModel implements Serializable {    //左上角三角图标    public static final int ONE = 1001;    //textview布局    public static final int TWO = 1002;    //edittext布局    public static final int THREE = 1003;    public int type;    public Object data;    //是否免费的标志    public boolean isFree;    public ItemModel(int type, Object data, boolean isFree) {        this.type = type;        this.data = data;    }}

好了前期的准备工作差不多了,现在我们就该对Adapter中的逻辑进行处理了。先上Adapter的完整代码

public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.BaseViewHolder> {    private ArrayList<ItemModel> dataList = new ArrayList<>();    private int lastPressIndex = -1;    private Context mContext;    public void replaceAll(ArrayList<ItemModel> list, Context context) {        mContext = context;        dataList.clear();        if (list != null && list.size() > 0) {            dataList.addAll(list);        }        notifyDataSetChanged();    }    @Override    public DemoAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        switch (viewType) {            case ItemModel.ONE:                ///左上角三角标识布局;                return new CornorViewHoler(LayoutInflater.from(parent.getContext()).inflate(R.layout.corner_one, parent, false));            case ItemModel.TWO:                return new OneViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.one, parent, false));            case ItemModel.THREE:                return new TWoViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.two, parent, false));        }        return null;    }    @Override    public void onBindViewHolder(DemoAdapter.BaseViewHolder holder, int position) {        holder.setData(dataList.get(position).data);    }    @Override    public int getItemViewType(int position) {        return dataList.get(position).type;    }    @Override    public int getItemCount() {        return dataList != null ? dataList.size() : 0;    }    public class BaseViewHolder extends RecyclerView.ViewHolder {        public BaseViewHolder(View itemView) {            super(itemView);        }        void setData(Object data) {        }    }    private class OneViewHolder extends BaseViewHolder {        private TextView tv;        public OneViewHolder(View view) {            super(view);            tv = (TextView) view.findViewById(R.id.tv);            itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    Log.e("TAG", "OneViewHolder: ");                    notyfy = 0;                    int position = getAdapterPosition();                    ItemModel model = dataList.get(position);                    Log.e("TAG", "OneViewHolder: " + model.toString());                    EventBus.getDefault().post(model);                    if (lastPressIndex == position) {                        lastPressIndex = -1;                    } else {                        lastPressIndex = position;                    }                    notifyDataSetChanged();                }            });        }        @Override        void setData(Object data) {            if (data != null) {                String text = (String) data;                tv.setText(text);                if (getAdapterPosition() == lastPressIndex) {                    tv.setSelected(true);                    tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.white));                } else {                    tv.setSelected(false);                    tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.blue_500));                }            }        }    }    int notyfy = 0;    private class TWoViewHolder extends BaseViewHolder {        private EditText et;        private String chargeFunds;        public TWoViewHolder(View view) {            super(view);            et = (EditText) view.findViewById(R.id.et);            final int position = getAdapterPosition();            //ItemModel model = dataList.get(position);            //Log.e("TWoViewHolder", "TWoViewHolder: "+model.toString());            Log.e("TWoViewHolder", "TWoViewHolder: ");          et.setOnFocusChangeListener(new View.OnFocusChangeListener() {                @Override                public void onFocusChange(View v, boolean hasFocus) {                    if (hasFocus) {                        if (lastPressIndex != position) {                            notifyItemChanged(lastPressIndex);                            lastPressIndex = position;                        }                    }                }            });            et.addTextChangedListener(new TextWatcher() {                @Override                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {                }                @Override                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {                    if (charSequence != null || !charSequence.equals("")) {                        try {                            int str = Integer.parseInt(String.valueOf(charSequence));                            if (str < 9) {                                Toast.makeText(mContext, "输入的金额小于最小支付金额9元", Toast.LENGTH_SHORT).show();                                et.setSelection(et.getText().length());                            }                            if (str > 2000) {                                Toast.makeText(mContext, "输入的金额大于最大支付金额2000元", Toast.LENGTH_SHORT).show();                                et.setText("2000");                                et.setSelection(et.getText().length());                            }                        } catch (Exception e) {                            e.printStackTrace();                        }                    }                }                @Override                public void afterTextChanged(Editable editable) {                    if (editable.length() > 0) {                        String inputText = et.getText().toString().trim();                        if (Double.parseDouble(inputText) < 9) {                            chargeFunds = "9";                        } else if (Double.parseDouble(inputText) > 2000) {                            chargeFunds = "2000";                        } else {                            chargeFunds = inputText;                        }                    }                    String funds = chargeFunds + "元";                    ItemModel model = new ItemModel(ItemModel.THREE, funds, false);                    EventBus.getDefault().post(model);                }            });        }        @Override        void setData(Object data) {            super.setData(data);            final int position = getAdapterPosition();            if (position == lastPressIndex)                et.requestFocus();            else                et.clearFocus();        }    }    private class CornorViewHoler extends BaseViewHolder {        private TextView tv;        public CornorViewHoler(View view) {            super(view);            tv = (TextView) view.findViewById(R.id.tv);            //int position = getAdapterPosition();            //ItemModel model = dataList.get(position);            //Log.e("TAG", "OneViewHolder: "+model.toString());            itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    Log.e("TAG", "OneViewHolder: ");                    notyfy = 0;                    int position = getAdapterPosition();                    ItemModel model = dataList.get(position);                    EventBus.getDefault().post(model);                    if (lastPressIndex == position) {                        lastPressIndex = -1;                    } else {                        lastPressIndex = position;                    }                    notifyDataSetChanged();                }            });        }        @Override        void setData(Object data) {            if (data != null) {                String text = (String) data;                tv.setText(text);                if (getAdapterPosition() == lastPressIndex) {                    tv.setSelected(true);                    tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.white));                } else {                    tv.setSelected(false);                    tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.blue_500));                }            }        }    }}

上述代码中数据传递使用的是EventBus3.0,所以需要在gradle文件添加如下引用:

compile 'org.greenrobot:eventbus:3.0.0'

现在开始对Adapter类进行分析,在Adapter类中我们创建了3个ViewHolder(CornorViewHoler、TWoViewHolder、OneViewHolder)在这三个ViewHolder中实现各自的逻辑,同时三个类中同时继承了void setData(Object data) 接口处理是否为选中状态、是否需要更改背景颜色以及状态
其他部分的代码都比较简单,不过在处理TWoViewHolder这个类的时候有点小麻烦(EditText),首先大家看到EditText有一个取值范围的(9~2000),这个通过addTextChangedListener监听来实现即可

    et.addTextChangedListener(new TextWatcher() {                @Override                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {                }                @Override                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {                    if (charSequence != null || !charSequence.equals("")) {                        try {                            int str = Integer.parseInt(String.valueOf(charSequence));                            if (str < 9) {                                Toast.makeText(mContext, "输入的金额小于最小支付金额9元", Toast.LENGTH_SHORT).show();                                et.setSelection(et.getText().length());                            }                            if (str > 2000) {                                Toast.makeText(mContext, "输入的金额大于最大支付金额2000元", Toast.LENGTH_SHORT).show();                                et.setText("2000");                                et.setSelection(et.getText().length());                            }                        } catch (Exception e) {                            e.printStackTrace();                        }                    }                }                @Override                public void afterTextChanged(Editable editable) {                    if (editable.length() > 0) {                        String inputText = et.getText().toString().trim();                        if (Double.parseDouble(inputText) < 9) {                            chargeFunds = "9";                        } else if (Double.parseDouble(inputText) > 2000) {                            chargeFunds = "2000";                        } else {                            chargeFunds = inputText;                        }                    }                    String funds = chargeFunds + "元";                    ItemModel model = new ItemModel(ItemModel.THREE, funds, false);                    EventBus.getDefault().post(model);                }            });

到这里差不多写完了,是不是就大功告成了?别急,还有一个问题,点击EditText的时候,TextView的状态还没有消失呢,怎么办?

当页面刷新的时候 如果当前选中的是这个输入框就让它获取到并得到焦点,所以我们在TWoViewHolder类中的setData() 方法中让它获取焦点,将最后的位置传递给它

  @Override        void setData(Object data) {            super.setData(data);            final int position = getAdapterPosition();            if (position == lastPressIndex)                et.requestFocus();            else                et.clearFocus();        }

这样就差不多了,然后我们对EdiText的焦点进行监听(setOnFocusChangeListener),Notifycation布局文件即可

  et.setOnFocusChangeListener(new View.OnFocusChangeListener() {                @Override                public void onFocusChange(View v, boolean hasFocus) {                    if (hasFocus) {                        if (lastPressIndex != position) {                            notifyItemChanged(lastPressIndex);                            lastPressIndex = position;                        }                    }                 }            });

代码讲到这里就可以实现上面的效果了,下面将其他布局文件代码贴出来
MainActivity.class

public class MainActivity extends AppCompatActivity {    private RecyclerView recyclerView;    private DemoAdapter adapter;    private TextView tvPay;    private TextView tv_recharge_money;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tv_recharge_money = (TextView) findViewById(R.id.tv_recharge_money);        recyclerView = (RecyclerView) findViewById(R.id.recylerview);        tvPay = (TextView) findViewById(R.id.tvPay);        //setHasFixedSize 的作用就是确保尺寸是通过用户输入从而确保RecyclerView的尺寸是一个常数。        // RecyclerView 的Item宽或者高不会变(提升性能)。        recyclerView.setHasFixedSize(true);        //recycleview设置布局方式,GridView (一行三列)        recyclerView.setLayoutManager(new GridLayoutManager(this, 3));        recyclerView.setAdapter(adapter = new DemoAdapter());        adapter.replaceAll(getData(),this);        EventBus.getDefault().register(this);    }    public ArrayList<ItemModel> getData() {        String data = "3,9,30,50,100";        // isDiscount :1、有角标 2、无角标        String isDiscount = "2";        String dataArr[] = data.split(",");        ArrayList<ItemModel> list = new ArrayList<>();        for (int i = 0; i < dataArr.length; i++) {            String count = dataArr[i] + "元";            if (isDiscount.equals("1") && i == 0) {                list.add(new ItemModel(ItemModel.ONE, count, true));            } else {                list.add(new ItemModel(ItemModel.TWO, count, false));            }        }        list.add(new ItemModel(ItemModel.THREE, null, false));        return list;    }    @Subscribe(threadMode = ThreadMode.MAIN)    public void getAdapterClickInfo(ItemModel model) {        String money = model.data.toString().replace("元", "");        tv_recharge_money.setText(money);        if (model.isFree==true){            Toast.makeText(this,"点击的是带免费标签的",Toast.LENGTH_SHORT).show();        }else {            Toast.makeText(this,"点击的是正常标签的",Toast.LENGTH_SHORT).show();        }    }    @Override    protected void onDestroy() {        super.onDestroy();        EventBus.getDefault().unregister(this);    }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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"    tools:context="com.example.wangchang.testrecharge.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:layout_marginTop="12dp"            android:background="@color/grey_300" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="48dp"            android:background="@color/white"            android:gravity="center_vertical"            android:orientation="horizontal"            android:padding="8dp">            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="充值账号:"                android:textColor="@color/black" />            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="15013678968"                android:textColor="@color/yellow_900" />        </LinearLayout>        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:background="@color/grey_300" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="48dp"            android:background="@color/white"            android:gravity="center_vertical"            android:orientation="horizontal"            android:padding="8dp">            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="充值金额:"                android:textColor="@color/black" />            <TextView                android:id="@+id/tv_recharge_money"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="100"                android:textColor="@color/yellow_900" />        </LinearLayout>        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:background="@color/grey_300" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:padding="8dp"            android:text="选择充值金币:" />        <android.support.v7.widget.RecyclerView            android:id="@+id/recylerview"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:padding="12dp" />    </LinearLayout>    <TextView        android:id="@+id/tvPay"        android:layout_width="match_parent"        android:layout_height="48dp"        android:layout_alignParentBottom="true"        android:layout_margin="24dp"        android:background="@drawable/tv_bg_pay"        android:gravity="center"        android:text="立即充值"        android:textColor="@color/white" /></RelativeLayout>

corner_one.xml

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical">    <TextView        android:id="@+id/tv"        android:layout_width="match_parent"        android:layout_height="42dp"        android:gravity="center"        android:layout_margin="8dp"        android:padding="12dp"        android:background="@drawable/tv_bg"        android:textColor="@color/blue_500" />    <ImageView        android:layout_margin="8dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        app:srcCompat="@drawable/free_click"        android:id="@+id/imageView" /></FrameLayout>

one.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical">    <TextView        android:id="@+id/tv"        android:layout_width="match_parent"        android:layout_height="42dp"        android:gravity="center"        android:layout_margin="8dp"        android:padding="12dp"        android:background="@drawable/tv_bg"        android:textColor="@color/blue_500" /></LinearLayout>

two.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical">    <EditText        android:id="@+id/et"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_margin="8dp"        android:background="@drawable/bg_et"        android:gravity="center"        android:hint="9-2000元"        android:inputType="number"        android:padding="12dp"        android:textSize="12sp" /></LinearLayout>

好了,代码到此为止,效果也差不多了,有兴趣的朋友可以自行尝试下,欢迎大家一起交流,如有更好的建议或者意见可致电lcf_spark@163.com

5 0
原创粉丝点击