RecylerView(GridView佈局)實現充值界面效果

RecylerView(GridView佈局)實現充值界面效果

項目中有一個充值的效果以下: android

效果圖
以前爲了趕項目進度,也沒有多想,這不是很簡單的麼?5個TextView加1個EditText不就搞定了麼? 的確這樣作是能夠實現的,並且也在規定時間內完成了項目。(可是存在侷限性) 因爲項目中屢次的使用了RecycleView,而後發現這個用RecycleView實現效果會更好(佈局更靈活,不限制個數),完成後的效果:
有角標
無角標

  • 一、數據傳遞效果的展現 首先分析下這個界面須要的數據,因爲這個界面是後臺經過兩個字段判斷實現的效果
String data = "3,9,30,50,100";
   //isDiscount :一、有角標 二、無角標
	String isDiscount = "1";
複製代碼

咱們首先要經過IsDiscount這個字段來判斷是否顯示帶角標的控件,以及data字段來判斷動態添加幾個控件bash

  • 二、界面實現效果分析 一、組件選擇 文章開始就說到了,咱們選用的是RecycleView這個控件結合GridView佈局實現效果 二、RecyeView Adapter佈局分析 ①有角標TextView ②正常無角標TextView ③EditText輸入框 佈局如上三種,你們都知道RecycleView的強大,如今咱們就利用它其中的ItemType這個功能,RecyleView不少複雜的界面都是經過ItemType這個屬性來實現的。 三、具體代碼的實現 ①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的類用於處理數據app

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的完整代碼ide

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監聽來實現便可post

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() 方法中讓它獲取焦點,將最後的位置傳遞給它gradle

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

這樣就差很少了,而後咱們對EdiText的焦點進行監聽(setOnFocusChangeListener),Notifycation佈局文件便可ui

et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {

                        if (lastPressIndex != position) {
                            notifyItemChanged(lastPressIndex);
                            lastPressIndex = position;
                        }
                    } 
                }
            });
複製代碼

代碼講到這裏就能夠實現上面的效果了,下面將其餘佈局文件代碼貼出來 MainActivity.classthis

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 :一、有角標 二、無角標
        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

相關文章
相關標籤/搜索