Android基於開源專案的WheelView的時間、地址聯動選擇對話方塊
阿新 • • 發佈:2019-01-11
一晃離上次寫部落格差不多都過了半年了,現在工作中用到了一些實用的東西,想和大家分享一下。
現在實現的是一個基於開源專案WheelView的時間、地址聯動選擇的對話方塊,先看看效果圖,文章末尾有原始碼下載地址:
選擇時間:
選擇地點:
因為專案中要實現如圖上的效果,無奈WheelView的預設沒有,所以就修改了一點其中的程式碼和風格,就實現了這種效果。
步驟如下:
1、要實現選中字型變大,所以就得得到顯示文字的TextView的引用,所以這裡在原始碼“AbstractWheelTextAdapter”中添加了記錄顯示文字的TextView的集合、字型的最小顯示、最大顯示值以及記錄當前選中條目的索引:
<span style="white-space:pre"> </span>private int currentIndex = 0;
private static int maxsize = 24;
private static int minsize = 14;
private ArrayList<View> arrayList = new ArrayList<View>();
建構函式也隨之改為了:<span style="white-space:pre"> </span>protected AbstractWheelTextAdapter(Context context, int itemResource) { this(context, itemResource, NO_RESOURCE, 0, maxsize, minsize); }
<pre name="code" class="java"><span style="white-space:pre"> </span>protected AbstractWheelTextAdapter(Context context, int itemResource, int itemTextResource, int currentIndex, int maxsize, int minsize) { this.context = context; itemResourceId = itemResource; itemTextResourceId = itemTextResource; this.currentIndex = currentIndex; this.maxsize = maxsize; this.minsize = minsize; inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); }
其中currentIndex為初始化時選中字型變大的item的索引。
getView函式改為了:
<span style="white-space:pre"> </span>@Override
public View getItem(int index, View convertView, ViewGroup parent) {
if (index >= 0 && index < getItemsCount()) {
if (convertView == null) {
convertView = getView(itemResourceId, parent);
}
TextView textView = getTextView(convertView, itemTextResourceId);
if (!arrayList.contains(textView)) { //儲存顯示文字的TextView的引用,方便在外部呼叫
arrayList.add(textView);
}
if (textView != null) {
CharSequence text = getItemText(index);
if (text == null) {
text = "";
}
textView.setText(text);
if (index == currentIndex) { //把當前選中item字型改大,其餘的變小
textView.setTextSize(maxsize);
} else {
textView.setTextSize(minsize);
}
if (itemResourceId == TEXT_VIEW_ITEM_RESOURCE) {
configureTextView(textView);
}
}
return convertView;
}
return null;
}
這樣Adapter就修改完了。2、樣式的修改:
在WheelView中修改漸變顏色,中部為白色,向兩邊慢慢變暗
/** Top and bottom shadows colors */
private static final int[] SHADOWS_COLORS = new int[] { 0xeeffffff, 0xeaffffff, 0x33ffffff };
wheel_val.xml檔案改為了<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#22ffffff"
android:centerColor="#00ffffff"
android:endColor="#22ffffff"
android:angle="90" />
</shape>
wheel_bg.xml改為了空
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
</layer-list>
就實現了圖片中的效果,這樣對原始碼的修改就完成了。3、選擇時間對話方塊的實現,程式碼如下:
佈局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ly_myinfo_changebirth"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/ly_myinfo_changebirth_child"
android:layout_width="300dip"
android:layout_height="wrap_content"
android:layout_marginLeft="27dip"
android:layout_marginRight="27dip"
android:background="@drawable/bg_dialog_selector"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_share_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="14dip"
android:layout_marginLeft="18dip"
android:layout_marginTop="18dip"
android:gravity="center_vertical"
android:text="選擇日期"
android:textColor="#000000"
android:textSize="18sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="160dip"
android:orientation="horizontal"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:gravity="center_vertical">
<com.ywl5320.pickaddress.wheel.widget.views.WheelView
android:id="@+id/wv_birth_year"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
/>
<com.ywl5320.pickaddress.wheel.widget.views.WheelView
android:id="@+id/wv_birth_month"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
/>
<com.ywl5320.pickaddress.wheel.widget.views.WheelView
android:id="@+id/wv_birth_day"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="25dip"
android:layout_marginBottom="21dip">
<TextView
android:id="@+id/btn_myinfo_sure"
android:layout_width="77dip"
android:layout_height="33dip"
android:layout_alignParentRight="true"
android:layout_marginRight="15dip"
android:text="確認"
android:gravity="center"
android:textSize="16sp" />
<TextView
android:id="@+id/btn_myinfo_cancel"
android:layout_width="77dip"
android:layout_height="33dip"
android:layout_toLeftOf="@+id/btn_myinfo_sure"
android:text="取消"
android:gravity="center"
android:textSize="16sp" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
對話方塊style:<style name="ShareDialog" parent="@android:Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
對話方塊原始碼:package com.ywl5320.pickaddress;
import java.util.ArrayList;
import java.util.Calendar;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.ywl5320.pickaddress.wheel.widget.adapters.AbstractWheelTextAdapter;
import com.ywl5320.pickaddress.wheel.widget.views.OnWheelChangedListener;
import com.ywl5320.pickaddress.wheel.widget.views.OnWheelScrollListener;
import com.ywl5320.pickaddress.wheel.widget.views.WheelView;
/**
* 日期選擇對話方塊
*
* @author ywl
*
*/
public class ChangeBirthDialog extends Dialog implements android.view.View.OnClickListener {
private Context context;
private WheelView wvYear;
private WheelView wvMonth;
private WheelView wvDay;
private View vChangeBirth;
private View vChangeBirthChild;
private TextView btnSure;
private TextView btnCancel;
private ArrayList<String> arry_years = new ArrayList<String>();
private ArrayList<String> arry_months = new ArrayList<String>();
private ArrayList<String> arry_days = new ArrayList<String>();
private CalendarTextAdapter mYearAdapter;
private CalendarTextAdapter mMonthAdapter;
private CalendarTextAdapter mDaydapter;
private int month; //選中當前年有幾個月
private int day; //選中當前月有幾天(分了閏年的)
private int currentYear = getYear(); //得到當前年份
private int currentMonth = 1;
private int currentDay = 1;
private int maxTextSize = 24; //字型最大值
private int minTextSize = 14; //字型最小值
private boolean issetdata = false; //判斷是否設定了預設時間,沒有就設定為當前時間
private String selectYear; //選中的年
private String selectMonth; //選中的月
private String selectDay; //選中的日
private OnBirthListener onBirthListener;
public ChangeBirthDialog(Context context) {
super(context, R.style.ShareDialog);
this.context = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_myinfo_changebirth);
wvYear = (WheelView) findViewById(R.id.wv_birth_year);
wvMonth = (WheelView) findViewById(R.id.wv_birth_month);
wvDay = (WheelView) findViewById(R.id.wv_birth_day);
vChangeBirth = findViewById(R.id.ly_myinfo_changebirth);
vChangeBirthChild = findViewById(R.id.ly_myinfo_changebirth_child);
btnSure = (TextView) findViewById(R.id.btn_myinfo_sure);
btnCancel = (TextView) findViewById(R.id.btn_myinfo_cancel);
vChangeBirth.setOnClickListener(this);
vChangeBirthChild.setOnClickListener(this);
btnSure.setOnClickListener(this);
btnCancel.setOnClickListener(this);
if (!issetdata) {
initData();
}
initYears();
<span style="white-space:pre"> </span>//初始化年,顯示可見條目數量,年份集合,當前設定年份、<span style="font-family: Arial, Helvetica, sans-serif;">字型大小</span>
mYearAdapter = new CalendarTextAdapter(context, arry_years, setYear(currentYear), maxTextSize, minTextSize);
<span style="white-space:pre"> </span>//可見5條
wvYear.setVisibleItems(5);
<span style="white-space:pre"> </span>//設定介面卡
wvYear.setViewAdapter(mYearAdapter);
<span style="white-space:pre"> </span>//根據當前傳入的年份,設定顯示年份
wvYear.setCurrentItem(setYear(currentYear));
initMonths(month);
mMonthAdapter = new CalendarTextAdapter(context, arry_months, setMonth(currentMonth), maxTextSize, minTextSize);
wvMonth.setVisibleItems(5);
wvMonth.setViewAdapter(mMonthAdapter);
wvMonth.setCurrentItem(setMonth(currentMonth));
initDays(day);
mDaydapter = new CalendarTextAdapter(context, arry_days, currentDay - 1, maxTextSize, minTextSize);
wvDay.setVisibleItems(5);
wvDay.setViewAdapter(mDaydapter);
wvDay.setCurrentItem(currentDay - 1);
<span style="white-space:pre"> </span>//為年份選中新增change事件,根據選中年份,聯動設定月份
wvYear.addChangingListener(new OnWheelChangedListener() {
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
// TODO Auto-generated method stub
String currentText = (String) mYearAdapter.getItemText(wheel.getCurrentItem());
selectYear = currentText;
setTextviewSize(currentText, mYearAdapter);
currentYear = Integer.parseInt(currentText);
setYear(currentYear);
initMonths(month);
mMonthAdapter = new CalendarTextAdapter(context, arry_months, 0, maxTextSize, minTextSize);
wvMonth.setVisibleItems(5);
wvMonth.setViewAdapter(mMonthAdapter);
wvMonth.setCurrentItem(0);
}
});
<span style="white-space:pre"> </span>//新增滾動事件,呼叫adapter中的顯示文字集合來改變字型大小
wvYear.addScrollingListener(new OnWheelScrollListener() {
@Override
public void onScrollingStarted(WheelView wheel) {
// TODO Auto-generated method stub
}
@Override
public void onScrollingFinished(WheelView wheel) {
// TODO Auto-generated method stub
String currentText = (String) mYearAdapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mYearAdapter);
}
});
wvMonth.addChangingListener(new OnWheelChangedListener() {
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
// TODO Auto-generated method stub
String currentText = (String) mMonthAdapter.getItemText(wheel.getCurrentItem());
selectMonth = currentText;
setTextviewSize(currentText, mMonthAdapter);
setMonth(Integer.parseInt(currentText));
initDays(day);
mDaydapter = new CalendarTextAdapter(context, arry_days, 0, maxTextSize, minTextSize);
wvDay.setVisibleItems(5);
wvDay.setViewAdapter(mDaydapter);
wvDay.setCurrentItem(0);
}
});
wvMonth.addScrollingListener(new OnWheelScrollListener() {
@Override
public void onScrollingStarted(WheelView wheel) {
// TODO Auto-generated method stub
}
@Override
public void onScrollingFinished(WheelView wheel) {
// TODO Auto-generated method stub
String currentText = (String) mMonthAdapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mMonthAdapter);
}
});
wvDay.addChangingListener(new OnWheelChangedListener() {
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
// TODO Auto-generated method stub
String currentText = (String) mDaydapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mDaydapter);
selectDay = currentText;
}
});
wvDay.addScrollingListener(new OnWheelScrollListener() {
@Override
public void onScrollingStarted(WheelView wheel) {
// TODO Auto-generated method stub
}
@Override
public void onScrollingFinished(WheelView wheel) {
// TODO Auto-generated method stub
String currentText = (String) mDaydapter.getItemText(wheel.getCurrentItem());
setTextviewSize(currentText, mDaydapter);
}
});
}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//初始化年份,可以把1950設定為一個變數,方便動態設定
public void initYears() {
for (int i = getYear(); i > 1950; i--) {
arry_years.add(i + "");
}
}
<span style="white-space:pre"> </span>//初始化月份
public void initMonths(int months) {
arry_months.clear();
for (int i = 1; i <= months; i++) {
arry_months.add(i + "");
}
}
<span style="white-space:pre"> </span>//出事話天日
public void initDays(int days) {
arry_days.clear();
for (int i = 1; i <= days; i++) {
arry_days.add(i + "");
}
}
private class CalendarTextAdapter extends AbstractWheelTextAdapter {
ArrayList<String> list;
protected CalendarTextAdapter(Context context, ArrayList<String> list, int currentItem, int maxsize, int minsize) {
super(context, R.layout.item_birth_year, NO_RESOURCE, currentItem, maxsize, minsize);
this.list = list;
setItemTextResource(R.id.tempValue);
}
@Override
public View getItem(int index, View cachedView, ViewGroup parent) {
View view = super.getItem(index, cachedView, parent);
return view;
}
@Override
public int getItemsCount() {
return list.size();
}
@Override
protected CharSequence getItemText(int index) {
return list.get(index) + "";
}
}
<span style="white-space:pre"> </span>//暴露給activity的回撥藉口,用於獲取選擇的結果
public void setBirthdayListener(OnBirthListener onBirthListener) {
this.onBirthListener = onBirthListener;
}
@Override
public void onClick(View v) {
if (v == btnSure) {
if (onBirthListener != null) {
onBirthListener.onClick(selectYear, selectMonth, selectDay);
}
} else if (v == btnSure) {
} else if (v == vChangeBirthChild) {
return;
} else {
dismiss();
}
dismiss();
}
public interface OnBirthListener {
public void onClick(String year, String month, String day);
}
/**
* 設定字型大小
*
* @param curriteItemText
* @param adapter
*/
public void setTextviewSize(String curriteItemText, CalendarTextAdapter adapter) {
ArrayList<View> arrayList = adapter.getTestViews();
int size = arrayList.size();
String currentText;
for (int i = 0; i < size; i++) {
TextView textvew = (TextView) arrayList.get(i);
currentText = textvew.getText().toString();
if (curriteItemText.equals(currentText)) {
textvew.setTextSize(maxTextSize);
} else {
textvew.setTextSize(minTextSize);
}
}
}
public int getYear() {
Calendar c = Calendar.getInstance();
return c.get(Calendar.YEAR);
}
public int getMonth() {
Calendar c = Calendar.getInstance();
return c.get(Calendar.MONTH) + 1;
}
public int getDay() {
Calendar c = Calendar.getInstance();
return c.get(Calendar.DATE);
}
public void initData() {
setDate(getYear(), getMonth(), getDay());
this.currentDay = 1;
this.currentMonth = 1;
}
/**
* 設定年月日
*
* @param year
* @param month
* @param day
*/
public void setDate(int year, int month, int day) {
selectYear = year + "";
selectMonth = month + "";
selectDay = day + "";
issetdata = true;
this.currentYear = year;
this.currentMonth = month;
this.currentDay = day;
if (year == getYear()) {
this.month = getMonth();
} else {
this.month = 12;
}
calDays(year, month);
}
/**
* 設定年份
*
* @param year
*/
public int setYear(int year) {
int yearIndex = 0;
if (year != getYear()) {
this.month = 12;
} else {
this.month = getMonth();
}
for (int i = getYear(); i > 1950; i--) {
if (i == year) {
return yearIndex;
}
yearIndex++;
}
return yearIndex;
}
/**
* 設定月份
*
* @param year
* @param month
* @return
*/
public int setMonth(int month) {
int monthIndex = 0;
calDays(currentYear, month);
for (int i = 1; i < this.month; i++) {
if (month == i) {
return monthIndex;
} else {
monthIndex++;
}
}
return monthIndex;
}
/**
* 計算每月多少天
*
* @param month
* @param leayyear
*/
public void calDays(int year, int month) {
boolean leayyear = false;
if (year % 4 == 0 && year % 100 != 0) {
leayyear = true;
} else {
leayyear = false;
}
for (int i = 1; i <= 12; i++) {
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
this.day = 31;
break;
case 2:
if (leayyear) {
this.day = 29;
} else {
this.day = 28;
}
break;
case 4:
case 6:
case 9:
case 11:
this.day = 30;
break;
}
}
if (year == getYear() && month == getMonth()) {
this.day = getDay();
}
}
}
4、選擇地址過程基本一致,就不在這裡贅述了,唯一區別就是獲取地址源的時候,是通過解析json資料獲取的,我會上傳原始碼,無積分下載的。
好的這樣就完成了這種看似高大上的效果 哈哈哈 原始碼下載