Android自己定义NumberPicker
16lz
2021-01-26
在项目中使用要使用滑轮来选择时间,而android系统自带的NumberPicker样式和需求不一样,而且颜色默认的是蓝色的,字体只能为黑色,上下只能显示1个,效果如下图:
这样子满足不了我们的需求,但是大体功能还是和我们需求一样的,只是外貌不是我们想要的。我在网上看过一些资料后,和一些开源的项目,最终还是决定从numberPicker的源码下手,修改一些属性,以满足需求。经过一番修改后达到我们想要的结果,用一个小的demo作为演示,效果如下:
点击这里下载
大家可以看到在自定义的NumberPicker上显示的效果与原来的不一样,首先,线条不再为蓝色,可以自定义线条的颜色,中间的字体大小和颜色也可以根据自己的要求变更颜色,上下显示的个数,也可自己制定。
首先,简单介绍一下这个demo,这是一个简单个人信息的填写的demo,隐藏原来的软键盘,下面使用到了一个PopupWindow,在PopupWindow中添加两个控件:1、自定义的NumberPicker。2、自定义的数字键盘。
接下来,先看一下我的项目结构,我在这里使用的Android Studio,会和使用Eclipse的朋友结构会有所不一样
大家可以看到项目中只有3个类,NumberPicker和Scroller都是从源码中直接复制过来,只是修改了NumberPicker中的一些代码,和drawable中的一些样式,就可以达到修改NumberPicker的外观。大家使用NumberPicker时一定要将values中和drawable中的样式复制完全,不然程序会报错。
然后介绍一下布局文件:
接下来时PopupWindow的布局文件:
<?xml version="1.0" encoding="utf-8"?>
然后就是MainActivity的代码:
package com.example.liyachao.informationset;import android.app.Activity;import android.os.Bundle;import android.text.InputType;import android.util.Log;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.Button;import android.widget.EditText;import android.widget.PopupWindow;import android.widget.ScrollView;import android.widget.TableLayout;import android.widget.TextView;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;public class MainActivity extends Activity { private PopupWindow pw; private List editTexts; private View view; private ScrollView scrollView; ViewGroup.LayoutParams layoutParams; private Button pw_btn_done, pw_btn_last, pw_btn_next; private EditText sex; private EditText birth; private EditText weight; private EditText height; private EditText step; private EditText sensitive; private TextView one, two, three, four, five, six, seven, eight, nine, zero, delete, point; private List number; private String myNumber = ""; private NumberPicker numberPicker, sexPicker; private TableLayout tableLayout; private String sexStr; private String birthStr = "1990"; private String weightStr = "50 kg"; private String heightStr = "175 cm"; private String stepStr = "35 cm"; private String sensitiveStr = "5"; private String strValue[] = {sexStr, birthStr, weightStr, heightStr, stepStr, sensitiveStr}; private String str[] = new String[]{"男", "女"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); scrollView = (ScrollView) findViewById(R.id.scrollView); view = LayoutInflater.from(this).inflate(R.layout.pwpupwindow, null); layoutParams = scrollView.getLayoutParams(); editTexts = new ArrayList(); initView(); setPWView(); setListener(); } /** * 这只监听事件 */ private void setListener() { for (int i = 0; i < editTexts.size(); i++) { editTexts.get(i).setOnFocusChangeListener(new myFocusChangeListener()); } pw_btn_done.setOnClickListener(new myClickListener()); pw_btn_next.setOnClickListener(new myClickListener()); pw_btn_last.setOnClickListener(new myClickListener()); numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal, EditText editText) { for (int i = 0; i < editTexts.size(); i++) { if (editTexts.get(i).isFocused()) { editTexts.get(i).setText(picker.getValue() + ""); editTexts.get(i).setSelection(editTexts.get(i).getText().length()); strValue[i] = picker.getValue() + ""; break; } } } }); sexPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal, EditText editText) { sex.setText(str[picker.getValue()]); sex.setSelection(str[picker.getValue()].length()); strValue[0] = str[picker.getValue()]; } }); } /** * 初始化popupwindow中的控件 */ private void setPWView() { number = new ArrayList(); pw = new PopupWindow(view, WindowManager.LayoutParams.MATCH_PARENT, dp2px(350)); pw_btn_done = (Button) view.findViewById(R.id.done); pw_btn_last = (Button) view.findViewById(R.id.last); pw_btn_next = (Button) view.findViewById(R.id.next); numberPicker = (NumberPicker) view.findViewById(R.id.numberpicker); tableLayout = (TableLayout) view.findViewById(R.id.tableLayout); one = (TextView) view.findViewById(R.id.number_1); number.add(one); two = (TextView) view.findViewById(R.id.number_2); number.add(two); three = (TextView) view.findViewById(R.id.number_3); number.add(three); four = (TextView) view.findViewById(R.id.number_4); number.add(four); five = (TextView) view.findViewById(R.id.number_5); number.add(five); six = (TextView) view.findViewById(R.id.number_6); number.add(six); seven = (TextView) view.findViewById(R.id.number_7); number.add(seven); eight = (TextView) view.findViewById(R.id.number_8); number.add(eight); nine = (TextView) view.findViewById(R.id.number_9); number.add(nine); zero = (TextView) view.findViewById(R.id.number_0); number.add(zero); point = (TextView) view.findViewById(R.id.number_); number.add(point); delete = (TextView) view.findViewById(R.id.number_reduce); number.add(delete); for (int i = 0; i < number.size(); i++) { number.get(i).setOnClickListener(new NumberListener()); } sexPicker = (NumberPicker) view.findViewById(R.id.numberpicker1); numberPicker.setWrapSelectorWheel(false); } /** * 给自定义的数字键盘设置点击事件 */ private class NumberListener implements View.OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { case R.id.number_0: myNumber += "0"; break; case R.id.number_1: myNumber += "1"; break; case R.id.number_2: myNumber += "2"; break; case R.id.number_3: myNumber += "3"; break; case R.id.number_4: myNumber += "4"; break; case R.id.number_5: myNumber += "5"; break; case R.id.number_6: myNumber += "6"; break; case R.id.number_7: myNumber += "7"; break; case R.id.number_8: myNumber += "8"; break; case R.id.number_9: myNumber += "9"; break; case R.id.number_: myNumber += "."; break; case R.id.number_reduce: myNumber = myNumber.substring(0, myNumber.length() - 1); break; } for (int i = 0; i < editTexts.size(); i++) { if (editTexts.get(i).isFocused()) { String str = strValue[i].substring(strValue[i].length() - 3, strValue[i].length()); Log.i("tag", strValue[i]); editTexts.get(i).setText(myNumber + str); editTexts.get(i).setSelection(myNumber.length()); break; } } } } private class myFocusChangeListener implements View.OnFocusChangeListener { @Override public void onFocusChange(View v, boolean hasFocus) { switch (v.getId()) { case R.id.edit_sex: sexStr = sex.getText().toString().trim(); if (hasFocus) { tableLayout.setVisibility(View.GONE); sexPicker.setVisibility(View.VISIBLE); numberPicker.setVisibility(View.GONE); sexPicker.setWrapSelectorWheel(false); sexPicker.setMaxValue(1); sexPicker.setMinValue(0); sexPicker.setDisplayedValues(str); sex.setCursorVisible(true); sex.setSelection(1); } else { sex.setText(str[sexPicker.getValue()]); } break; case R.id.edit_birthday: if (hasFocus) { tableLayout.setVisibility(View.GONE); numberPicker.setVisibility(View.VISIBLE); sexPicker.setVisibility(View.GONE); numberPicker.setValue(Integer.parseInt(strValue[1])); numberPicker.setMaxValue(2015); numberPicker.setMinValue(1970); birth.setSelection(4); } else { birth.setText(strValue[1]); } break; case R.id.edit_weight: if (hasFocus) { tableLayout.setVisibility(View.VISIBLE); numberPicker.setVisibility(View.GONE); sexPicker.setVisibility(View.GONE); weight.setText(" kg"); } else { weight.setText(myNumber + " kg"); myNumber = ""; } break; case R.id.edit_height: if (hasFocus) { tableLayout.setVisibility(View.VISIBLE); numberPicker.setVisibility(View.GONE); sexPicker.setVisibility(View.GONE); height.setText(" cm"); } else { height.setText(myNumber + " cm"); myNumber = ""; } break; case R.id.edit_step: if (hasFocus) { tableLayout.setVisibility(View.VISIBLE); numberPicker.setVisibility(View.GONE); sexPicker.setVisibility(View.GONE); step.setText(" cm"); } else { step.setText(myNumber + " cm"); myNumber = ""; } break; case R.id.edit_sensitive: if (hasFocus) { tableLayout.setVisibility(View.GONE); numberPicker.setVisibility(View.VISIBLE); sexPicker.setVisibility(View.GONE); numberPicker.setValue(Integer.parseInt(strValue[5])); numberPicker.setMaxValue(10); numberPicker.setMinValue(1); sensitive.setText(sensitiveStr); sensitive.setSelection(sensitiveStr.length()); } else { sensitive.setText(strValue[5]); } break; } } } private class myClickListener implements View.OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { case R.id.done: layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; scrollView.setLayoutParams(layoutParams); pw.dismiss(); break; case R.id.last: for (int i = 0; i < editTexts.size(); i++) { if (editTexts.get(i).isFocused() && i != 0) { editTexts.get(i).clearFocus(); editTexts.get(i - 1).requestFocus(); break; } } break; case R.id.next: for (int i = 0; i < editTexts.size(); i++) { if (editTexts.get(i).isFocused() && i != (editTexts.size() - 1)) { editTexts.get(i).clearFocus(); editTexts.get(i + 1).requestFocus(); break; } } break; } } } private int dp2px(float value) { float v = getResources().getDisplayMetrics().density; return (int) (v * value + 0.5f); } private void initView() { sex = (EditText) findViewById(R.id.edit_sex); birth = (EditText) findViewById(R.id.edit_birthday); weight = (EditText) findViewById(R.id.edit_weight); height = (EditText) findViewById(R.id.edit_height); step = (EditText) findViewById(R.id.edit_step); sensitive = (EditText) findViewById(R.id.edit_sensitive); editTexts.add(sex); editTexts.add(birth); editTexts.add(weight); editTexts.add(height); editTexts.add(step); editTexts.add(sensitive); for (int i = 0; i < editTexts.size(); i++) { hideSoftInputMethod(editTexts.get(i)); editTexts.get(i).setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (pw.isShowing()) { layoutParams.height = dp2px(200); scrollView.setLayoutParams(layoutParams); } else { pw.showAtLocation(view, Gravity.BOTTOM, 0, 0); } return false; } }); } } /** * 一直隐藏软键盘 * * @param ed */ public void hideSoftInputMethod(EditText ed) { getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); int currentVersion = android.os.Build.VERSION.SDK_INT; String methodName = null; if (currentVersion >= 16) { // 4.2 methodName = "setShowSoftInputOnFocus"; } else if (currentVersion >= 14) { // 4.0 methodName = "setSoftInputShownOnFocus"; } if (methodName == null) { ed.setInputType(InputType.TYPE_NULL); } else { Class cls = EditText.class; Method setShowSoftInputOnFocus; try { setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class); setShowSoftInputOnFocus.setAccessible(true); setShowSoftInputOnFocus.invoke(ed, false); } catch (Exception e) { ed.setInputType(InputType.TYPE_NULL); e.printStackTrace(); } } }}
NumberPicker代码太长就不贴出来了,感兴趣的朋友可以下载下来研究研究。
更多相关文章
- 【笔记】颜色渐变标签之坑爹的 @android:color/transparent
- [送给不懂android的开发者]react-native如何替换android图标资源
- 向android 的状态栏中加入快捷按钮(home,back,menu等等)的方法(续)
- Android实时滤镜实现
- android全屏透明状态栏的坑
- android studio修改项目名,模块名,包名
- Android(安卓)移植到高清机顶盒csm1201[一]
- 如何在Android中使用汇编语言
- Android中怎么破解游戏之修改金币数