Android-PickerView的选项选择器、时间选择器的简单运用

前言
本文主要演示Android-PickerView的选项选择器、时间选择器的简单运用。由于每一个版本略有不用,所以实际使用方式以github项目wiki文档为准。

效果图

代码分析
本文使用的版本是compile ‘com.contrarywind:Android-PickerView:4.1.4’;

时间选择器搭配DateTimeHelper使用;

需要执行setDecorView方法,否则底部虚拟导航栏会显示在弹出的选择器区域;

使用步骤
一、项目组织结构图

注意事项:

1、 导入类文件后需要change包名以及重新import R文件路径

2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤
在APP中的bundle.gradle文件中添加以下代码,引入Android-PickerView控件
复制代码

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.why.project.pickerviewdemo"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    //PickerView
    compile 'com.contrarywind:Android-PickerView:4.1.4'
}

复制代码
三、使用方法
在colors.xml文件中添加以下代码
复制代码

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <!-- **************************pickerview选择器常用颜色值********************************** -->
    <color name="pickerview_divider_color">#9D9D9D</color>
    <color name="pickerview_cancel_text_color">#979696</color>
    <color name="pickerview_submit_text_color">#FAA359</color>
    <color name="pickerview_title_text_color">#1A78EC</color>
    <color name="pickerview_center_text_color">#333333</color>
</resources>

复制代码
布局文件
需要以RelativeLayout为根布局(LinearLayout不合适,其他的比如FrameLayout可能可以,需要尝试),主要用于setDecorView方法。

复制代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_rootview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">

    <LinearLayout
        android:id="@+id/optionsPickerLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_margin="10dp">

        <!-- 选择爱好 -->
        <TextView
            android:id="@+id/hobbyTv"
            android:layout_width="0.0dp"
            android:layout_weight="1"
            android:layout_height="38dp"
            android:gravity="center_vertical"
            android:text="选择爱好"
            android:textSize="16sp"
            android:textColor="#3090d9"
            android:drawableRight="@drawable/pickerview_jiantou"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:background="#E7E7E7"
            android:layout_marginRight="10dp"
            />

        <!-- 选择地址 -->
        <TextView
            android:id="@+id/addressTv"
            android:layout_width="0.0dp"
            android:layout_weight="1"
            android:layout_height="38dp"
            android:gravity="center_vertical"
            android:text="选择地址"
            android:textSize="16sp"
            android:textColor="#3090d9"
            android:drawableRight="@drawable/pickerview_jiantou"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:background="#E7E7E7"
            />

    </LinearLayout>

    <!-- 开始时间 -->
    <TextView
        android:id="@+id/startdateTv"
        android:layout_alignLeft="@+id/optionsPickerLayout"
        android:layout_below="@+id/optionsPickerLayout"
        android:layout_width="wrap_content"
        android:layout_height="38dp"
        android:gravity="center_vertical"
        android:text="开始日期"
        android:textSize="16sp"
        android:textColor="#3090d9"
        android:drawableLeft="@drawable/date_icon"
        android:drawablePadding="5dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:layout_marginTop="10dp"
        android:background="#E7E7E7"
        />
复制代码 MainActivity 黄色标记的是选项选择器常规写法;

橙色标记的是选项选择器常规之外的实现文本滑动的效果;

复制代码

package com.why.project.pickerviewdemo;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bigkoo.pickerview.builder.OptionsPickerBuilder;
import com.bigkoo.pickerview.builder.TimePickerBuilder;
import com.bigkoo.pickerview.listener.OnOptionsSelectListener;
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
import com.bigkoo.pickerview.view.OptionsPickerView;
import com.bigkoo.pickerview.view.TimePickerView;
import com.why.project.pickerviewdemo.bean.SpinnearBean;
import com.why.project.pickerviewdemo.util.DateTimeHelper;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

public class MainActivity extends AppCompatActivity {

    private TextView hobbyTv;//选择爱好
    /**爱好列表集合*/
    private ArrayList<SpinnearBean> mHobbyList;
    private ArrayList<String> mHobbyNameList;//用于选择器显示
    private OptionsPickerView mHobbyPickerView;//选择器

    private TextView addressTv;//选择地址
    /**地址列表集合*/
    private ArrayList<SpinnearBean> mAddressList;
    private ArrayList<String> mAddressNameList;//用于选择器显示
    private OptionsPickerView mAddressPickerView;//选择器

    private TextView startdateTv;//开始日期
    private TimePickerView mStartDatePickerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        initDatas();
        initEvents();
    }

    private void initViews() {
        hobbyTv = findViewById(R.id.hobbyTv);
        addressTv = (TextView) findViewById(R.id.addressTv);
        //实现文本区域可滑动的效果,用于当显示的文本过长时
        addressTv.setMovementMethod(ScrollingMovementMethod.getInstance());//实现可滑动,但是和ScrollView滑动冲突,需要处理下
        //https://blog.csdn.net/qq_36070190/article/details/70053228
        addressTv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                if(event.getAction()==MotionEvent.ACTION_DOWN){
                    //通知父控件不要干扰
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                }
                if(event.getAction()==MotionEvent.ACTION_MOVE){
                    //通知父控件不要干扰
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                }
                if(event.getAction()==MotionEvent.ACTION_UP){
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                }
                return false;
            }
        });
        startdateTv = findViewById(R.id.startdateTv);
    }

    private void initDatas() {
        //========================================初始化爱好列表集合========================================
        mHobbyList = new ArrayList<SpinnearBean>();
        mHobbyNameList = new ArrayList<String>();

        //模拟获取数据集合
        try{
            mHobbyList = parseJsonArray("spinners.txt");
        }catch (Exception e) {
            e.printStackTrace();
        }
        for(SpinnearBean spinnearBean : mHobbyList){
            mHobbyNameList.add(spinnearBean.getParaName());
        }

        //============初始化选择器============
        initHobbyOptionPicker();
        //如果想要直接赋值的话,这样写
        /*if(mHobbyNameList.size() > 0){
            hobbyTv.setText(mHobbyNameList.get(0));//默认展现第一个
        }*/

        //========================================初始化地址列表集合========================================
        mAddressList = new ArrayList<SpinnearBean>();
        mAddressNameList = new ArrayList<String>();
        //模拟获取数据集合
        try{
            mAddressList = parseJsonArray("spinners2.txt");
        }catch (Exception e) {
            e.printStackTrace();
        }
        for(SpinnearBean spinnearBean : mAddressList){
            mAddressNameList.add(spinnearBean.getParaName());
        }
        //============初始化选择器============
        initAddressOptionPicker();
        //当选择器列表项文本过长时,直接赋值的话,会有问题:高度变小了。不太明白什么原因,所以需要延迟设置文本,实际过程中因为有网络请求,所以一般没有问题
        /*new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if(mAddressNameList.size() > 0){
                    addressTv.setText(mAddressNameList.get(0));//默认展现第一个
                }
            }
        }, 500);*/

        //========================================初始化开始日期选择器控件========================================
        initStartTimePicker();//初始化开始日期选择器控件
    }

    //初始化爱好选择器
    private void initHobbyOptionPicker() {
        mHobbyPickerView = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int option2, int options3, View v) {
                        //返回的分别是三个级别的选中位置
                        String tx = mHobbyNameList.get(options1);
                        hobbyTv.setText(tx);
                    }
                })
                .setDecorView((RelativeLayout)findViewById(R.id.activity_rootview))//必须是RelativeLayout,不设置setDecorView的话,底部虚拟导航栏会显示在弹出的选择器区域
                .setTitleText("选择爱好")//标题文字
                .setTitleSize(20)//标题文字大小
                .setTitleColor(getResources().getColor(R.color.pickerview_title_text_color))//标题文字颜色
                .setCancelText("取消")//取消按钮文字
                .setCancelColor(getResources().getColor(R.color.pickerview_cancel_text_color))//取消按钮文字颜色
                .setSubmitText("确定")//确认按钮文字
                .setSubmitColor(getResources().getColor(R.color.pickerview_submit_text_color))//确定按钮文字颜色
                .setContentTextSize(20)//滚轮文字大小
                .setTextColorCenter(getResources().getColor(R.color.pickerview_center_text_color))//设置选中文本的颜色值
                .setLineSpacingMultiplier(1.8f)//行间距
                .setDividerColor(getResources().getColor(R.color.pickerview_divider_color))//设置分割线的颜色
                .setSelectOptions(0)//设置选择的值
                .build();

        mHobbyPickerView.setPicker(mHobbyNameList);//添加数据
    }

    //初始化地址选择器
    private void initAddressOptionPicker() {
        mAddressPickerView = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {
            @Override
            public void onOptionsSelect(int options1, int option2, int options3, View v) {
                //返回的分别是三个级别的选中位置
                String tx = mAddressNameList.get(options1);
                addressTv.setText(tx);
            }
        })
                .setDecorView((RelativeLayout)findViewById(R.id.activity_rootview))//必须是RelativeLayout,不设置setDecorView的话,底部虚拟导航栏会显示在弹出的选择器区域
                .setTitleText("选择地址")//标题文字
                .setTitleSize(20)//标题文字大小
                .setTitleColor(getResources().getColor(R.color.pickerview_title_text_color))//标题文字颜色
                .setCancelText("取消")//取消按钮文字
                .setCancelColor(getResources().getColor(R.color.pickerview_cancel_text_color))//取消按钮文字颜色
                .setSubmitText("确定")//确认按钮文字
                .setSubmitColor(getResources().getColor(R.color.pickerview_submit_text_color))//确定按钮文字颜色
                .setContentTextSize(20)//滚轮文字大小
                .setTextColorCenter(getResources().getColor(R.color.pickerview_center_text_color))//设置选中文本的颜色值
                .setLineSpacingMultiplier(1.8f)//行间距
                .setDividerColor(getResources().getColor(R.color.pickerview_divider_color))//设置分割线的颜色
                .setSelectOptions(0)//设置选择的值
                .build();

        mAddressPickerView.setPicker(mAddressNameList);//添加数据
    }
/**初始化开始日期选择器控件*/
private void initStartTimePicker() {
    //控制时间范围(如果不设置范围,则使用默认时间1900-2100年,此段代码可注释)
    //因为系统Calendar的月份是从0-11的,所以如果是调用Calendar的set方法来设置时间,月份的范围也要是从0-11
    Calendar selectedDate = Calendar.getInstance();
    //设置最小日期和最大日期
    Calendar startDate = Calendar.getInstance();
    try {
        startDate.setTime(DateTimeHelper.parseStringToDate("1970-01-01"));//设置为2006年4月28日
    } catch (ParseException e) {
        e.printStackTrace();
    }
    Calendar endDate = Calendar.getInstance();//最大日期是今天

    //时间选择器
    mStartDatePickerView = new TimePickerBuilder(MainActivity.this, new OnTimeSelectListener() {
                @Override
                public void onTimeSelect(Date date, View v) {//选中事件回调
                    // 这里回调过来的v,就是show()方法里面所添加的 View 参数,如果show的时候没有添加参数,v则为null
                    startdateTv.setText(DateTimeHelper.formatToString(date,"yyyy-MM-dd"));
                }
            })
            .setDecorView((RelativeLayout)findViewById(R.id.activity_rootview))//必须是RelativeLayout,不设置setDecorView的话,底部虚拟导航栏会显示在弹出的选择器区域
            //年月日时分秒 的显示与否,不设置则默认全部显示
            .setType(new boolean[]{true, true, true, false, false, false})
            .setLabel("", "", "", "", "", "")
            .isCenterLabel(false)//是否只显示中间选中项的label文字,false则每项item全部都带有label。
            .setTitleText("开始日期")//标题文字
            .setTitleSize(20)//标题文字大小
            .setTitleColor(getResources().getColor(R.color.pickerview_title_text_color))//标题文字颜色
            .setCancelText("取消")//取消按钮文字
            .setCancelColor(getResources().getColor(R.color.pickerview_cancel_text_color))//取消按钮文字颜色
            .setSubmitText("确定")//确认按钮文字
            .setSubmitColor(getResources().getColor(R.color.pickerview_submit_text_color))//确定按钮文字颜色
            .setContentTextSize(20)//滚轮文字大小
            .setTextColorCenter(getResources().getColor(R.color.pickerview_center_text_color))//设置选中文本的颜色值
            .setLineSpacingMultiplier(1.8f)//行间距
            .setDividerColor(getResources().getColor(R.color.pickerview_divider_color))//设置分割线的颜色
            .setRangDate(startDate, endDate)//设置最小和最大日期
            .setDate(selectedDate)//设置选中的日期
            .build();
}

private void initEvents() {
    //选择爱好的下拉菜单点击事件
    hobbyTv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mHobbyPickerView.show();
        }
    });

    //选择地址的下拉菜单点击事件
    addressTv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mAddressPickerView.show();
        }
    });

    //开始日期的下拉菜单点击事件
    startdateTv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mStartDatePickerView.show();
        }
    });
}





/*===========读取assets目录下的js字符串文件(js数组和js对象),然后生成List集合===========*/
public static final String LISTROOTNODE = "spinnerList";
public static final String KEY_LISTITEM_NAME = "paraName";
public static final String KEY_LISTITEM_VALUE = "paraValue";
public static final String KEY_LISTITEM_CHECKCOLOR = "checkColor";

/**
 * 解析JSON文件的简单数组
 */
private ArrayList<SpinnearBean> parseJsonArray(String fileName) throws Exception{

    ArrayList<SpinnearBean> itemsList = new ArrayList<SpinnearBean>();

    String jsonStr = getStringFromAssert(MainActivity.this, fileName);
    if(jsonStr.equals("")){
        return null;
    }
    JSONObject allData = new JSONObject(jsonStr);  //全部内容变为一个项
    JSONArray jsonArr = allData.getJSONArray(LISTROOTNODE); //取出数组
    for(int x = 0;x<jsonArr.length();x++){
        SpinnearBean model = new SpinnearBean();
        JSONObject jsonobj = jsonArr.getJSONObject(x);
        model.setParaName(jsonobj.getString(KEY_LISTITEM_NAME));
        model.setParaValue(jsonobj.getString(KEY_LISTITEM_VALUE));
        if(jsonobj.has(KEY_LISTITEM_CHECKCOLOR)){
            model.setCheckColor(jsonobj.getString(KEY_LISTITEM_CHECKCOLOR));
        }
        model.setSelectedState(false);
        itemsList.add(model);
        model = null;
    }
    return itemsList;
}

/**
 * 访问assets目录下的资源文件,获取文件中的字符串
 * @param filePath - 文件的相对路径,例如:"listdata.txt"或者"/www/listdata.txt"
 * @return 内容字符串
 * */
public String getStringFromAssert(Context mContext, String filePath) {

    String content = ""; // 结果字符串
    try {
        InputStream is = mContext.getResources().getAssets().open(filePath);// 打开文件
        int ch = 0;
        ByteArrayOutputStream out = new ByteArrayOutputStream(); // 实现了一个输出流
        while ((ch = is.read()) != -1) {
            out.write(ch); // 将指定的字节写入此 byte 数组输出流
        }
        byte[] buff = out.toByteArray();// 以 byte 数组的形式返回此输出流的当前内容
        out.close(); // 关闭流
        is.close(); // 关闭流
        content = new String(buff, "UTF-8"); // 设置字符串编码
    } catch (Exception e) {
        Toast.makeText(mContext, "对不起,没有找到指定文件!", Toast.LENGTH_SHORT)
                .show();
    }
    return content;
}

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作者jaaksi,源码pickerview,一个非常好用的 Android PickerView 库,内部提供 3 种常用类型的 Picker,支持扩展自定义 PickerTimePicker时间选择器,支持聚合模式的时间选择器(合并 v1.x 的 MixedTimePicker)OptionPicker:联动选择器效果图  APKDemo App下载连接PickerView READMEPicker通过组装 PickerView 实现常用的 Picker 选择器。上面已经列举提供的 3 中常用的 Picker。BasePickerPicker 基类:封装了 TopBar,PickerView 容器,create and add PickerView 方法,Picker 弹窗等方法。 三种 Picker 都继承自 BasePicker,你也可以继承它扩展自己的 Picker。APIapidescriptionsetPickerBackgroundColor设置 picker 背景setPadding设置 PickerView 父容器 padding 单位:pxsetTag给 Picker 设置 tag,用于区分不同的 picker 等。用法同 View setTaggetRootLayout获取 PickerView 的父容器,创建 DefaultTopBar 时必须指定setOnPickerChooseListener设置 picker 取消,确定按钮监听。可用于拦截选中操作setTopBar设置自定义 TopBarsetInterceptor设置拦截器createPickerView创建 PickerViewgetPickerViews获取 Picker 中所有的 pickerview 集合addPicker将创建的 PickerView 添加到上面集合中,createPickerView 内部已调用该方法findPickerViewByTag通过 tag 找到对应的 PickerViewisScrolling是否滚动未停止。滚动未停止的时候,不响应 Picker 的取消,确定按键getPickerDialog获取 Picker 弹窗。可以在 new 之后设置 dialog 属性show显示 picker 弹窗对比 github 上最受欢迎的同类库 Android-PickerView ,本库将 TopBar 等通用相关逻辑封装在基类中,并提供代码中创建 PickerView 方法,不需要再依赖 xml。用户自定义 Picker 时,继承 BasePicker,只需要处理自己的逻辑即可,简单便捷。 而对 Android-PickerView 来说,实现自定义 Picker,依然需要处理 TopBar 等逻辑,造成大量重复代码。TopBarTopBar:TopBar 通过抽象接口 ITopBar 来管理,实现 Picker 与 TopBar 的解耦。提供默认实现 DefaultTopBar。可实现接口定制自己的 TopBar。   public interface ITopBar {      /**       * @return topbar view       */      View getTopBarView();      /**       * @return 取消按钮 view       */      View getBtnCancel();      /**       * @return 确定按钮 view       */      View getBtnConfirm();      /**       * @return title view       */      TextView getTitleView();    }DefaultTopBar APIapidescriptionsetDividerColor设置 topbar bottom line colorsetDividerHeight设置 bottom divider line heightgetDivider获取 TopBar bottom linegetTitleView获取 TopBar title viewInterceptor拦截器:用于在 pickerview 创建时拦截,设置 pickerview 的属性。Picker 内部并不提供对 PickerView 的设置方法,而是通过 Interceptor 实现。这种设计用来实现 PickerPickerView 的属性设置完美解耦。   private void init(){     mTimePicker.setInterceptor(new 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值