Android 自定義含有滾動選擇器的對話方塊
阿新 • • 發佈:2019-02-08
1.概述
使用LIstView和Dialog實 自定義含有滾動選擇器的對話方塊,可以設定顯示字型的不同顏色,設定字型透明度,設定大小,設定顯示多少項。下面給兩個效果:
顯示7項,字型透明度和大小改變 | 顯示5項,字型顏色和大小改變 |
---|---|
2.使用方法:
首先將本文最後的程式碼粘到對應的檔案位置,然後在gradle配置中新增如下依賴:
compile 'com.android.support.constraint:constraint-layout:1.0.2'
建立WheelListDialog 物件。Context為上下文,data為將要顯示的資料,為ArrayList型別。
WheelListDialog dialog=new WheelListDialog(Context
context,ArrayList<String>data);
給下面兩個按鈕設定監聽事件
dialog.setListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id .btOk:
Toast.makeText(MainActivity.this, dialog.getPositionData(),
Toast.LENGTH_SHORT).show();
dialog.dismiss();
break;
case R.id.btCancel:
dialog.dismiss();
break ;
default:
break;
}
}
});
顯示:
dialog.show();
下面是預設效果(不去設定字型透明度,大小,顏色和顯示數量)
下面會以顯示7項(3+1+3)為例講解,當然也可以是3項5項等。因為是7項所以設定:
顏色,字型,透明度陣列長度都必須是4(3+1)
相對的如果是顯示3項,顏色,字型,透明度陣列長度都必須是2(1+1),中間一項之上就只有1項。
繼續講7項的情況:中間之上有3項(3+1+3嘛):
dialog.setShowNum(3);
可以設定顏色,依次為從中間向兩邊的顏色,為了方便,可以如下匯入::
import static android.graphics.Color.*;
......
int[] textColor = {BLACK, YELLOW, RED, BLUE};
dialog.setTextColor(textColor);
...
設定字型大小,同樣是從中間向兩邊
int[] textSize = {15, 13, 12, 10};
dialog.setTextSize(textSize);
設定透明度
float textAlpha[] = {1.0f, 0.8f, 0.7f, 0.5f}
dialog.setTextAlpha(textAlpha);
以上設定完成後的效果:
再舉個例子,這次不設定顏色,中間一項之上只有兩項(2+1+2=5(項)):
List<String> data = new ArrayList<>();
for (int i = 0; i < 20; i++) {
data.add("第" + i + "項");
}
final WheelListDialog dialog = new WheelListDialog(this, data);
float textAlpha[] = {1.0f, 0.6f, 0.4f};
int[] textSize = {15, 13, 11};
dialog.setTextAlpha(textAlpha);
dialog.setShowNum(2);
dialog.setTextAlpha(textAlpha);
dialog.setTextSize(textSize);
dialog.setListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btOk:
Toast.makeText(MainActivity.this, dialog.getPositionData(), Toast.LENGTH_SHORT).show();
dialog.dismiss();
break;
case R.id.btCancel:
dialog.dismiss();
break;
default:
break;
}
}
});
dialog.show();
效果:
3.程式碼資料,如上文所說使用
WheelListDialog.java:
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.constraint.ConstraintLayout;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.a10234736.test2.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by HeTingwei on 2018/2/3.
* 以listView仿照wheelView(的樣子)可以設定顯示字型透明度,大小
*/
public class WheelListDialog extends AlertDialog {
private static final String TAG = "WheelListDialog";
private ListView mViewList;
private int firstPosition;
private View line1;
private View line2;
private ConstraintLayout constraintLayout;
private View view;
private Button btOk, btCancel;
private Context mContext;
private List<String> data = new ArrayList<>();
private List<String> showData = new ArrayList<>();
private WheelListAdapter adapter;
private int showNum = 3;//中間子項上方顯示子項數目
private int textColor[] = {Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK};//預設黑色
private int textSize[] = {15, 13, 12, 10};//字型大小,從中間向外側排列,這裡是預設值
private int color = -1;
private int size=-1;
private float textAlpha[] = {1.0f, 0.8f, 0.7f, 0.5f};//字型透明度,從中間向外側排列,這裡是預設值
private int itemHeight = dp2px(40);//每個子項高度為40dp
private View.OnClickListener listener;
//初始化,設定顯示資料
public WheelListDialog(@NonNull Context context, List<String> data) {
super(context,R.style.style_dialog);
mContext = context;
this.data = data;
view = LayoutInflater.from(context).inflate(R.layout.wheel_list, null);
}
//設定一個值,讓顯示字型顏色一致
public void setTextColor(int textColor) {
this.textColor = new int[showNum + 1];
for (int i = 0; i <showNum+1 ; i++) {
this.textColor[i] = textColor;
}
}
//設定一個值,讓顯示字型大小一致
public void setTextSize(int textSize) {
this.textSize = new int[showNum+1];
for (int i = 0; i <showNum+1 ; i++) {
this.textSize[i] = textSize;
}
}
//獲取點選位置
public String getPositionData(){
return showData.get(firstPosition);
}
//點選按鈕監聽
public void setListener(View.OnClickListener listener){
this.listener = listener;
}
//設定顯示在中間之上的子項的數目
public void setShowNum(int num) {
showNum = num;
}
//設定顯示字型大小,由中間向兩側排列
public void setTextSize(int[] textSize) {
this.textSize = textSize;
}
//設定顯示字型透明度,由中間向兩側排列
public void setTextAlpha(float[] textAlpha) {
this.textAlpha = textAlpha;
}
//設定字型顏色,由中間向兩側排列
public void setTextColor(int[] textColor) {
this.textColor = textColor;
}
private void initView() {
line1 = view.findViewById(R.id.line1);
line2 = view.findViewById(R.id.line2);
constraintLayout = (ConstraintLayout)view.findViewById(R.id.constraintLayout);
mViewList = (ListView) view.findViewById(R.id.list_view);
//設定大小
ConstraintLayout.LayoutParams p = (ConstraintLayout.LayoutParams) constraintLayout.getLayoutParams();
p.height = itemHeight * (showNum * 2 + 1)-2;
ConstraintLayout.LayoutParams p1 = (ConstraintLayout.LayoutParams) line1.getLayoutParams();
p1.topMargin = itemHeight * showNum;
ConstraintLayout.LayoutParams p2 = (ConstraintLayout.LayoutParams) line2.getLayoutParams();
p2.topMargin = itemHeight * (showNum + 1);
btCancel = (Button)view.findViewById(R.id.btCancel);
btOk = (Button)view.findViewById(R.id.btOk);
adapter = new WheelListAdapter(mContext, showData);
mViewList.setAdapter(adapter);
mViewList.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER);
mViewList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
if (position - showNum >= 0 && position < showData.size() - showNum) {
if (position + 1 == firstPosition + showNum) {
mViewList.smoothScrollBy(-dp2px(40), 300);
mViewList.postDelayed(new Runnable() {
@Override
public void run() {
mViewList.requestFocusFromTouch();
mViewList.setSelection(position - showNum);
}
}, 300);
} else if (position < firstPosition + showNum) {
mViewList.smoothScrollByOffset(position - showNum - firstPosition + 1);
firstPosition = position - showNum + 1;
} else {
mViewList.smoothScrollByOffset(position - showNum - firstPosition);
firstPosition = position - showNum;
}
adapter.change(position);
}
}
});
mViewList.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (AbsListView.OnScrollListener.SCROLL_STATE_IDLE == scrollState) {
mViewList.smoothScrollToPosition(firstPosition);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
Log.d(TAG, "onItemClick: " + firstVisibleItem);
if (firstVisibleItem < firstPosition) {
firstPosition = firstVisibleItem;
adapter.change(firstVisibleItem + showNum);
} else if (firstVisibleItem > firstPosition) {
firstPosition = firstVisibleItem;
adapter.change(firstVisibleItem + showNum);
}
}
});
btOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, "第" + firstPosition + "項", Toast.LENGTH_SHORT).show();
WheelListDialog.this.dismiss();
}
});
btCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
WheelListDialog.this.dismiss();
}
});
}
private int dp2px(float dipValue) {
final float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
private boolean checkDataIsWrong() {
if (textAlpha != null && textSize != null &&
textSize.length == textAlpha.length &&
textSize.length == showNum + 1 &&
textColor.length == showNum + 1) return true;
try {
throw new Exception("The data is wrong!Please check the variable:textSize,textAlpha,and showNum");
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Override
public void show() {
super.show();
// if (!checkDataIsWrong()) return;
//讓前面和後面都空出來
for (int i = 0; i < showNum; i++) {
showData.add("");
}
showData.addAll(data);
for (int i = 0; i < showNum; i++) {
showData.add("");
}
initView();
setContentView(view);
Window window = getWindow();
WindowManager.LayoutParams p = window.getAttributes();
p.height = WindowManager.LayoutParams.WRAP_CONTENT;
p.width = WindowManager.LayoutParams.WRAP_CONTENT;
p.dimAmount = 0.0f;
window.setGravity(Gravity.CENTER);
window.setAttributes(p);
}
//listView的介面卡
class WheelListAdapter extends BaseAdapter {
List<String> data;
Context mContext;
List<TextBean> beanList = new ArrayList<>();
public WheelListAdapter(Context mContext, List<String> data) {
this.data = data;
this.mContext = mContext;
for (String str : data) {
beanList.add(new TextBean(str));
}
//初始化最先顯示的資料
for (int i = 0; i < showNum + 1; i++) {
beanList.get(i).setAlphaAndSize(textAlpha[showNum - i], textSize[showNum - i]);
beanList.get(i).setColor(textColor[showNum - i]);
}
for (int i = showNum + 1; i < showNum * 2 + 1; i++) {
beanList.get(i).setAlphaAndSize(textAlpha[i - showNum], textSize[i - showNum]);
beanList.get(i).setColor(textColor[i - showNum]);
}
beanList.get(showNum * 2 + 1).setAlphaAndSize(textAlpha[textAlpha.length - 1],
textSize[textSize.length - 1]);
beanList.get(showNum * 2 + 1).setColor(textColor[textColor.length - 1]);
}
@Override
public int getCount() {
return data.size();
}
@Override
public String getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.wheel_list_item,
parent, false);
} else {
view = convertView;
}
TextView textView = (TextView)view.findViewById(R.id.text);
TextBean text = beanList.get(position);
textView.setText(text.getText());
textView.setAlpha(text.getAlpha());
textView.setTextSize(text.getSize());
textView.setTextColor(text.getColor());
return view;
}
private void change(int position) {
for (int i = 0; i < showNum + 1; i++) {
if (position + i < beanList.size()) {
beanList.get(position + i).setAlphaAndSize(textAlpha[i], textSize[i]);
beanList.get(position + i).setColor(textColor[i]);
}
if (position - i >= 0) {
beanList.get(position - i).setAlphaAndSize(textAlpha[i], textSize[i]);
beanList.get(position - i).setColor(textColor[i]);
}
}
if (position + showNum + 1 < beanList.size()) {
beanList.get(position + showNum + 1).setAlphaAndSize(textAlpha[showNum], textSize[showNum]);
beanList.get(position + showNum + 1).setColor(textColor[showNum]);
}
if (position - showNum - 1 >= 0) {
beanList.get(position - showNum - 1).setAlphaAndSize(textAlpha[showNum], textSize[showNum]);
beanList.get(position - showNum - 1).setColor(textColor[showNum]);
}
notifyDataSetChanged();
}
}
class TextBean {
int size = 15;
float alpha = 1.0f;
String text;
int color;
public TextBean(String text) {
this.text = text;
}
public void setAlphaAndSize(Float alpha, int size) {
this.alpha = alpha;
this.size = size;
}
public int getSize() {
return size;
}
public float getAlpha() {
return alpha;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
}
}
dialog佈局檔案:wheel_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="@android:color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/white">
<android.support.constraint.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="200dp"
android:layout_height="282dp"
android:layout_marginTop="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:listSelector="@android:color/transparent"
android:scrollbars="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"></ListView>
<View
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="120dp"
android:background="@android:color/black"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<View
android:id="@+id/line2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="160dp"
android:background="@android:color/black"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
<LinearLayout
app:layout_constraintTop_toBottomOf="@id/constraintLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
>
<Button
android:id="@+id/btCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:background="#00000000"
android:onClick="click1"
android:text="取消"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout"/>
<Button
android:id="@+id/btOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:layout_marginTop="0dp"
android:background="#00000000"
android:onClick="click2"
android:text="確定"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
listView子項佈局檔案:wheel_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<TextView
android:id="@+id/text"
android:textStyle="bold"
android:text="123"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
在values/strings.xml下,新增以下程式碼:
<style name="style_dialog" parent="android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
</style>