美文网首页Android
Android底部选择器

Android底部选择器

作者: leaflying | 来源:发表于2020-05-18 15:39 被阅读0次

因为有些需求,自己也在不断的学习的过程中,所以就搞了一个简单的底部选择器,如果大家有发现需要调整的地方,希望大家指出,谢谢


QQ图片20200518153847.jpg

先发个图片,然后呢,就慢慢整理代码。
首先就定义一下动画的样式,这里是一个从底部上滑进入和下滑退出的样式。
set_up_out.xml

<?xml version="1.0" encoding="utf-8"?><!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromYDelta="50%p"
        android:toYDelta="0" />
</set>

set_up_in.xml

<?xml version="1.0" encoding="utf-8"?><!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="200"
        android:fromYDelta="0"
        android:toYDelta="50%p" />
</set>

在style.xml中加入

   <style name="AnimUp" parent="@android:style/Animation">
        <item name="android:windowEnterAnimation">@anim/set_up_in</item>
        <item name="android:windowExitAnimation">@anim/set_up_out</item>
    </style>

然后呢我就开始贴代码了

package com.example.qmuitest.Selector;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
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.ListView;
import android.widget.PopupWindow;

import com.example.qmuitest.R;

public class SelectorPopWindow {
    private static PopupWindow mPopupWindow;
    private static Builder mBuilder;
    private static Window mWindow;
    private static View mContentView;

    private SelectorPopWindow() {
        mBuilder = new Builder();
    }

    public static Builder newBuilder() {
        if (mBuilder == null) {
            mBuilder = new Builder();
        }
        return mBuilder;
    }

    /**
     * 获取PopupWindow宽度
     */
    public int getWidth() {
        if (mPopupWindow != null) {
            return mContentView.getMeasuredWidth();
        }
        return 0;
    }


    /**
     * 获取PopupWindow高度
     */
    public int getHeight() {
        if (mPopupWindow != null) {
            return mContentView.getMeasuredHeight();
        }
        return 0;
    }




    public SelectorPopWindow show(View view) {
        if (view.getVisibility() == View.GONE) {
            mPopupWindow.showAtLocation(view, Gravity.NO_GRAVITY, 0, 0);
        } else {
            int[] location = new int[2];
            view.getLocationOnScreen(location);
            if (mPopupWindow != null) {
                mPopupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
            }
        }
        return this;
    }

    public static void dismiss() {
        if (mWindow != null) {
            WindowManager.LayoutParams params = mWindow.getAttributes();
            params.alpha = 1.0f;
            mWindow.setAttributes(params);
        }
        if (mPopupWindow != null && mPopupWindow.isShowing())
            mPopupWindow.dismiss();
    }

    public interface ViewClickListener {
        void getChildView(PopupWindow mPopupWindow, View view, int mLayoutResId);
    }

    public static class Builder implements PopupWindow.OnDismissListener{
        private Context mContext;
        private int mLayoutResId;//布局ID
        private int mWidth, mHeight;//弹窗宽高
        private int mAnimationStyle;//动画样式
        private SelectorAdapter mAdapter;
        private Drawable mDrawable;//背景Drawable
        private boolean mTouchable = true;//是否相应touch事件
        private boolean mFocusable = true;//是否获取焦点
        private boolean mOutsideTouchable = true;//设置外部是否点击
        private boolean mBackgroundDarkEnable = false;//是否背景窗体变暗
        private ViewClickListener mListener;//子View监听回调
        private float mDarkAlpha = 1.0f;//透明值
        public SelectorPopWindow build(Context context) {
            this.mContext = context;
            SelectorPopWindow popWindow = new SelectorPopWindow();
            apply();
            if (mListener != null && mLayoutResId != 0) {
                mListener.getChildView(mPopupWindow, mContentView, mLayoutResId);
            }
            return popWindow;
        }

        /**
         * 设置子View点击事件回调
         *
         * @param listener
         * @return
         */
        public Builder setViewOnClickListener(ViewClickListener listener) {
            this.mListener = listener;
            return this;
        }

        private void apply(){
            mContentView = LayoutInflater.from(mContext).inflate(mLayoutResId, null);
            if (mWidth != 0 && mHeight != 0) {
                mPopupWindow = new PopupWindow(mContentView, mWidth, mHeight);
            } else {
                mPopupWindow = new PopupWindow(mContentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            }

            if (mAnimationStyle != -1) {
                mPopupWindow.setAnimationStyle(mAnimationStyle);
            }

            ListView listView = mContentView.findViewById(R.id.item_list);

            listView.setAdapter(mAdapter);

            if (mDrawable != null) {
                mPopupWindow.setBackgroundDrawable(mDrawable);
            } else {
                mPopupWindow.setBackgroundDrawable(new ColorDrawable());
            }

            mPopupWindow.setTouchable(mTouchable);
            mPopupWindow.setFocusable(mFocusable);
            mPopupWindow.setOutsideTouchable(mOutsideTouchable);

            Activity activity = (Activity) mContext;
            mWindow = activity.getWindow();
            WindowManager.LayoutParams params = mWindow.getAttributes();
            params.alpha = 0.7f;
            mWindow.setAttributes(params);

            mPopupWindow.setOnDismissListener(this);
            mPopupWindow.update();
        }

        public Builder setSize(int width,int height){
            this.mWidth = width;
            this.mHeight = height;
            return  this;
        }

        public Builder setAdapter(SelectorAdapter adapter) {
            this.mAdapter = adapter;
            return this;
        }

        public Builder setmLayoutResId(int mLayoutResId) {
            this.mLayoutResId = mLayoutResId;
            return this;
        }

        public Builder setOutsideTouchable(boolean touchable) {
            mOutsideTouchable = touchable;
            return this;
        }

        public Builder setTouchable(boolean touchable) {
            mTouchable = touchable;
            return this;
        }

        public Builder setFocusable(boolean focusable) {
            mFocusable = focusable;
            return this;
        }

        public Builder setDrawable(Drawable drawable) {
            this.mDrawable = drawable;
            return this;
        }

        public Builder setmAnimationStyle(int mAnimationStyle) {
            this.mAnimationStyle = mAnimationStyle;
            return this;
        }

        @Override
        public void onDismiss() {
            dismiss();
        }
    }
}

package com.example.qmuitest.Selector;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.example.qmuitest.R;

import java.util.ArrayList;
import java.util.List;

public class SelectorAdapter extends BaseAdapter {

    List<ItemInterface> itemList =  new ArrayList<>();
    private Context context;

    public SelectorAdapter( Context context) {
        this.context = context;
    }

    public Context getContext() {
        return context;
    }

    @Override
    public int getCount() {
        return itemList.size();
    }

    @Override
    public Object getItem(int position) {
        return itemList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public void setItemList(List<ItemInterface> itemList) {
        this.itemList = itemList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        ViewHolder viewHolder;
        if(convertView == null){
            view = LayoutInflater.from(getContext()).inflate(R.layout.item_layout,parent,false);
            viewHolder = new ViewHolder();
            viewHolder.tv_name = view.findViewById(R.id.item_address_tv);
            view.setTag(viewHolder);
        }else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }
        viewHolder.tv_name.setText(itemList.get(position).getName());
        return view;
    }

    class ViewHolder{
        public TextView tv_name;
    }
}

package com.example.qmuitest.Selector;

import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import com.example.qmuitest.R;

public class Selector implements SelectorPopWindow.ViewClickListener {
    private View view;
    private Context context;
    private SelectorAdapter selectorAdapter;
    private OnItemClickListener onItemClickListener;


    public Selector(Context context,View view, SelectorAdapter selectorAdapter) {
        this.context = context;
        this.view = view;
        this.selectorAdapter = selectorAdapter;
    }

    public Context getContext() {
        return context;
    }

    public void show() {
        int screenHeigh =getContext().getResources().getDisplayMetrics().heightPixels;
        SelectorPopWindow.newBuilder()
                .setAdapter(selectorAdapter)
                .setViewOnClickListener(this)
                .setmAnimationStyle(R.style.AnimUp)
                .setDrawable(new BitmapDrawable())
                .setFocusable(true)
                .setOutsideTouchable(true)
                .setmLayoutResId(R.layout.selector_layout)
                .setSize(ViewGroup.LayoutParams.MATCH_PARENT, Math.round(screenHeigh * 0.6f))
                .build(getContext())
                .show(view);
    }

    public interface OnItemClickListener{
         void onItemClick(int position);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    @Override
    public void getChildView(final PopupWindow mPopupWindow, View view, int mLayoutResId) {
        if (mLayoutResId == R.layout.selector_layout) {
            ImageView imageBtn = view.findViewById(R.id.img_guanbi);
            ListView listView = view.findViewById(R.id.item_list);

            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    if(onItemClickListener!=null){
                        onItemClickListener.onItemClick(position);
                    }
                    mPopupWindow.dismiss();
                }
            });
            imageBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mPopupWindow.dismiss();
                }
            });
        }
    }
}

package com.example.qmuitest.Selector;

public interface ItemInterface {
    String getName();
    String getId();
}

贴两个样式文件
item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:layout_width="match_parent">
    <TextView
        android:id="@+id/item_address_tv"
        android:layout_height="wrap_content"
        android:textSize="15.3sp"
        android:textColor="#333333"
        android:layout_gravity="center"
        android:gravity="center"
        android:paddingLeft="4dp"
        android:paddingTop="13.3dp"
        android:paddingBottom="13.3dp"
        android:layout_width="match_parent"/>
</LinearLayout>

selector_layout.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="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_alignParentBottom="true"
    android:background="#fff"
    android:orientation="vertical"
    android:padding="1dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:id="@+id/cl_head"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            android:layout_marginTop="10dp"
            app:layout_constraintRight_toRightOf="parent"
            android:text="请选择"
            android:id="@+id/title"
            android:textColor="#777777"
            android:textSize="18sp" />

        <ImageView
            android:id="@+id/img_guanbi"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_alignParentRight="true"
            android:layout_marginRight="15dp"
            app:layout_constraintTop_toTopOf="@id/title"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="@id/title"
            android:src="@drawable/guanbi" />
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#e5e5e5"
            android:layout_marginTop="10dp"
            app:layout_constraintTop_toBottomOf="@id/title"/>
    </androidx.constraintlayout.widget.ConstraintLayout>

    <ListView
        android:id="@+id/item_list"
        android:layout_width="match_parent"
        android:layout_below="@id/cl_head"
        android:layout_height="match_parent" />

</RelativeLayout>

然后就开始调用了

package com.example.qmuitest;


import com.example.qmuitest.Selector.ItemInterface;

public class AdressItem implements ItemInterface {
    private String name;
    private String id;

    public void setName(String name) {
        this.name = name;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getId() {
        return id;
    }
}

package com.example.qmuitest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.example.qmuitest.Selector.ItemInterface;
import com.example.qmuitest.Selector.Selector;
import com.example.qmuitest.Selector.SelectorAdapter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        final TextView textView = findViewById(R.id.test);

       textView.setOnClickListener(new View.OnClickListener(){
           @Override
           public void onClick(View v) {
               final SelectorAdapter selectorAdapter = new SelectorAdapter(TestActivity.this);
               Selector selector = new Selector(TestActivity.this,textView,selectorAdapter);
               selector.setOnItemClickListener(new Selector.OnItemClickListener() {
                   @Override
                   public void onItemClick(int position) {
                       textView.setText(((ItemInterface)selectorAdapter.getItem(position)).getName());
                   }
               });
               selector.show();

               new Thread(new Runnable() {
                   @Override
                   public void run() {
                       OkHttpClient okHttpClient= new OkHttpClient();
                       Request request = new Request.Builder().url("http://guolin.tech/api/china").build();
                       try {
                           Response response = okHttpClient.newCall(request).execute();

                           final String data = response.body().string();
                           runOnUiThread(new Runnable() {
                               @Override
                               public void run() {
                                   ArrayList<ItemInterface> adressItems = new Gson().fromJson(data,new TypeToken<List<AdressItem>>(){}.getType());
                                   selectorAdapter.setItemList(adressItems);
                                   selectorAdapter.notifyDataSetChanged();

                               }
                           });
                       } catch (IOException e) {
                           e.printStackTrace();
                       }
                   }
               }).start();
           }
       });
    }
}

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TestActivity">
    <TextView
        android:layout_width="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:id="@+id/test"
        android:text="请选择"
        android:layout_height="wrap_content"></TextView>
</androidx.constraintlayout.widget.ConstraintLayout>

相关文章

网友评论

    本文标题:Android底部选择器

    本文链接:https://www.haomeiwen.com/subject/epnuohtx.html