1. 程式人生 > >Android 自定義含有滾動選擇器的對話方塊

Android 自定義含有滾動選擇器的對話方塊

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>