自定义View之GridView单选 金额选择Layout-ChooseMoneyLayout

思路:

  外层控件用的是GridView,里面每个item放一个FrameLayout,FrameLayout里面有Checkbox和ImageView,chechBox添加background实现选中效果,选中背景为透明,显示item的勾勾图标,不选中checkbox就有背景,挡住选中的勾勾。。重写GridView,实现监听和数据适配,用一个接口返回选中的数据。

代码:

ChooseMoneyLayout.java

public class ChooseMoneyLayout extends GridView {

    private int[] moneyList = {};   //数据源

    private LayoutInflater mInflater;  

    private MyAdapter adapter;   //适配器

    int defaultChoose = 0;     //默认选中项

    public ChooseMoneyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        setData();
    }

    public void setData() {
        mInflater = LayoutInflater.from(getContext());
        //配置适配器
        adapter = new MyAdapter();
        setAdapter(adapter);
    }

    /**
     * 设置默认选择项目,
     * @param defaultChoose
     */
    public void setDefaultPositon(int defaultChoose) {
        this.defaultChoose = defaultChoose;
        adapter.notifyDataSetChanged();
    }

    /**
     * 设置数据源
     * @param moneyData
     */
    public void setMoneyData(int[] moneyData){
        this.moneyList = moneyData;
    }

    class MyAdapter extends BaseAdapter {

        private CheckBox checkBox;

        @Override
        public int getCount() {
            return moneyList.length;
        }

        @Override
        public Object getItem(int position) {
            return moneyList[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            MyViewHolder holder;
            if (convertView == null) {
                holder = new MyViewHolder();
                convertView = mInflater.inflate(R.layout.item_money_pay, parent, false);
                holder.moneyPayCb = (CheckBox) convertView.findViewById(R.id.money_pay_cb);
                convertView.setTag(holder);
            } else {
                holder = (MyViewHolder) convertView.getTag();
            }

            holder.moneyPayCb.setText(getItem(position) + "元");

            holder.moneyPayCb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        //设置选中文字颜色
                        buttonView.setTextColor(getResources().getColor(R.color.light_color_blue));

                        //取消上一个选择
                        if (checkBox != null) {
                            checkBox.setChecked(false);
                        }
                        checkBox = (CheckBox) buttonView;
                    } else {
                        checkBox = null;
                        //设置不选中文字颜色
                        buttonView.setTextColor(getResources().getColor(R.color.darkgray));
                    }
                    //回调
                    listener.chooseMoney(position, isChecked, (Integer) getItem(position));
                }
            });

            if (position == defaultChoose) {
                defaultChoose = -1;
                holder.moneyPayCb.setChecked(true);
                checkBox = holder.moneyPayCb;
            }

            return convertView;
        }

        private class MyViewHolder {
            private CheckBox moneyPayCb;
        }
    }

    /**
     * 解决嵌套显示不完
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }

    private onChoseMoneyListener listener;

    public void setOnChoseMoneyListener(onChoseMoneyListener listener) {
        this.listener = listener;
    }

    public interface onChoseMoneyListener {
        /**
         * 选择金额返回
         *
         * @param position gridView的位置
         * @param isCheck  是否选中
         * @param moneyNum 钱数
         */
        void chooseMoney(int position, boolean isCheck, int moneyNum);
    }
}

item_money_pay.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:descendantFocusability="blocksDescendants">

<!-- 选中时候的图片 -->
    <ImageView
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_gravity="right|bottom"
        android:layout_marginBottom="3dp"
        android:layout_marginRight="3dp"
        android:maxHeight="9dp"
        android:maxWidth="9dp"
        android:scaleType="fitCenter"
        android:src="@drawable/money_pay_type_choose" />

    <CheckBox
        android:id="@+id/money_pay_cb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:background="@drawable/money_pay_selector"
        android:button="@null"
        android:gravity="center"
        android:paddingBottom="2.5dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingTop="2.5dp"
        android:textSize="20sp"
        android:textColor="#ff777777"
        />

</FrameLayout>

CheckBox的background: money_pay_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:drawable="@drawable/blue_border_noback_drawable"/>
    <item android:state_selected="true" android:drawable="@drawable/blue_border_noback_drawable"/>
    <item android:state_checked="true" android:drawable="@drawable/blue_border_noback_drawable"/>

    <item >

        <shape>
            <solid android:color="#ffffffff"/>
            <corners android:radius="5dp"/>
            <stroke android:color="#ffbfbfbf"
                android:width="1dp"/>
        </shape>

    </item>

</selector>

activity xml:

<com.minstone.view.ChooseMoneyLayout
            android:id="@+id/money_chose_money"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:horizontalSpacing="17dp"
            android:numColumns="3"
            android:verticalSpacing="20dp" />

activity里面代码:

private ChooseMoneyLayout moneyChoseMoney;
    private int money; //当前选择的金额

    private void initData() {
        //获取控件
        moneyChoseMoney = (ChooseMoneyLayout)findViewById(R.id.money_chose_money);
        //数设置据源
        moneyChoseMoney.setMoneyData(new int[]{30, 50, 100, 200, 300, 500,1000});
        //设置默认选中项
        moneyChoseMoney.setDefaultPositon(3);
        //金额选择监听
        moneyChoseMoney.setOnChoseMoneyListener(new ChooseMoneyLayout.onChoseMoneyListener() {
            @Override
            public void chooseMoney(int position,boolean isCheck, int moneyNum) {
                if(isCheck){
                    money = moneyNum;
                    ToastUtil.showCustomToast(PayActivity.this,money+"");
                }else{
                    money = 0;
                }
            }
        });

    }

  

时间: 2024-10-17 11:45:09

自定义View之GridView单选 金额选择Layout-ChooseMoneyLayout的相关文章

Android自定义View 简单实现多图片选择控件

前言 相信很多朋友在开发中都会遇到图片上传的情况,尤其是多图上传,最 经典的莫过于微信的图片选择了.所有很多情况下会使用到多图选择. 所以就有了这篇文章,今天抽点时间写了个控件. 支持自定义选择图片的样式 支持设置图片选择数量 支持图片预览,删除 支持图片拍照 先来看看效果 实现分析 假如不定义控件,我们要实现这样一个功能,无非是写个GridView在item点击的时候去显示图片进行选择,在返回界面的时候进行GridView的数据刷新.我们把这些逻辑写在我们自定义的GridView中,就成了一个

UI--从学习styleable自定义view属性到一点儿更有意思的尝试

<代码里的世界> -UI篇 用文字札记描绘自己 android学习之路 转载请保留出处 by Qiao http://blog.csdn.net/qiaoidea/article/details/45599593 [导航] - 多行文本折叠展开 自定义布局View实现多行文本折叠和展开 1.概述 前面封装view的时候用到了自定义属性,觉得有必要单独讲一下这部分,但是呢,又不想向其他文章一样千篇一律地写这些东西.所以呢,后便会加一些临时的发散思维,引用点有意思的东西.分享东西嘛,随性点儿. 回

Android自定义View和Canvas绘图解析

自定义view的流程分为measure. layout.draw三个主要步骤,今天我们通过源码来分下下measure的过程 我们从顶级view开始,顶级view即DecorView, view的事件都是先经过这个DecorView, 接下来我们来看看这个DecorView的MeasureSpec的创建过程: ViewRoot 对应 ViewRootImpl类,  是连接WindowManager 和 DecorView的纽带,   进入ViewRootImpl中,查看measureHierarc

自定义View系列教程05--示例分析

自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 PS:如果觉得文章太长,那就直接看视频吧 之前结合源码分析完了自定义View的三个阶段:measure,layout,draw. 那么,自定义有哪几种常见的方式呢? 直接继承自View 在使用该方式实现自定义View时通常的核心操作都在onDraw

【Android】自定义View、画布Canvas与画笔Paint

安卓自定义View其实很简单.这个View可以像<[Android]利用Java代码布局,按钮添加点击事件>(点击打开链接)一样,利用Java代码生成一系列的组件.也可以配合画布Canvas与画笔Paint来使用. 下面用一个例子来说明.如下图,有一个自定义布局View,里面摆放着,利用画布Canvas与画笔Paint绘制出来的蓝色正方形与红色文字. 在res\layout\activity_main.xml中,直接像摆放安卓固有组件一样,可以直接使用这个我定义组件.里面有蓝色正方形与红色文字

Android中的普通对话框、单选对话框、多选对话框、带Icon的对话框、以及自定义Adapter和自定义View对话框详解

对话框就是一个AlertDialog,但是一个简单的AlertDialog,我们却可以将它玩出许多花样来,下面我们就来一起总结一下AlertDialog的用法.看看各位童鞋在平时的工作中否都用到了AlertDialog的这些特性. OK,废话不多说,进入我们今天的正题. 普通对话框 普通对话框就是我们最最常用的对话框,实现起来并不复杂,实现出来的效果当然也是最简单的,如下: AlertDialog dialog = new AlertDialog.Builder(this).setTitle("

Android自定义View(RollWeekView-炫酷的星期日期选择控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53420889 本文出自:[openXu的博客] 目录: 1分析 2定义控件布局 3定义CustomWeekView 4重写onMeasure 5点击后执行动画 7重置预备控件 源码下载 ??最近收到一个自定义控件的需求,需要做一个日期选择控件,实现图如下: ???? ??一次展示一个星期的5天,中间放大的为当前选中的:如果点击了其中一个日期,比如星期五,那么整体向左滑动,并将星期五慢慢放大

继承于Layout的自定义View减少布局层次

不管是为了封装也好,实现特殊的效果也好,大家或多或少都会进行自定义View的实践,这中间又主要有两种:一种是继承于View或ViewGroup,还有一个是继承于各种已存在的Layout使用XML来写. 今天要来讨论的是第二种,实践就不详细说了,这里主要是针对这种方式带来的布局层次过深的问题提出两个方案. 第一种,注意在布局xml中使用merge,千万不要误解这个只在FrameLayout时候才能用哦,这个的准确作用是在解析XML布局时由此标志位就不解析直接将这一层忽略,将下面层次的view直接添

Android开发之自定义View专题(三):自定义GridView

gridview作为android开发中常用的组件,其功能十分强大.但是,我们有时候有很多特殊的需求,需要在其基础上进行改造.有时候会有移动gridView中item位置的需求,这个网上已经有很多例子,博主就不在描述.今天博主讲的是移动gridView中item中的内容.博主没看过网上那些移动item位置的demo,不知道其原理是不是和博主想的一样.博主思考过,似乎博主的这种实现原理似乎也可以用作实现移动item位置.而之前博主百思不得其解的小米手机的桌面的自定义乱序排放,似乎也可以用这个原理去