美文网首页
Android 使用PopupWindow和SwipeMenuL

Android 使用PopupWindow和SwipeMenuL

作者: GODANDDEVIL | 来源:发表于2020-03-25 15:57 被阅读0次

    1、创建一个需要添加到PopupWindow里的View的布局文件,里面包含一个SwipeMenuListview,drop_down_listview.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.baoyz.swipemenulistview.SwipeMenuListView
            android:id="@+id/drop_down_listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorSelect"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    2、创建一个封装数据的Model,ListModel.java:

    class ListModel {
        String deviceName;
        ListModel(String deviceName){
            this.deviceName = deviceName;
        }
    }
    

    3、创建item的布局文件,listview_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <TextView
            android:id="@+id/listItem_title"
            android:layout_width="wrap_content"
            android:layout_height="35dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginLeft="10dp"
            android:gravity="center_vertical"
            android:textColor="@color/colorWhite"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    4、创建适配器,CustomListAdapter.java:

    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    import java.util.List;
    
    public class CustomListAdapter extends BaseAdapter {
        private List<ListModel> list;
        private LayoutInflater layoutInflater;
        CustomListAdapter(Context context, List<ListModel> list){
            this.list = list;
            layoutInflater = LayoutInflater.from(context);
        }
    
        @Override
        public int getCount() {
            return list.size();
        }
    
        @Override
        public Object getItem(int i) {
            return list.get(i);
        }
    
        @Override
        public long getItemId(int i) {
            return i;
        }
    
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder viewHolder;
            if (view==null){
                view = layoutInflater.inflate(R.layout.listview_item,viewGroup,false);
                viewHolder = new ViewHolder(view);
                view.setTag(viewHolder);
    
            }else {
                viewHolder = (ViewHolder) view.getTag();
            }
            ListModel model = list.get(i);
            viewHolder.titleTextView.setText(model.deviceName);
            return view;
        }
    
        static class ViewHolder{
            TextView titleTextView;
            ViewHolder(View view){
                titleTextView = view.findViewById(R.id.listItem_title);
            }
        }
    }
    

    5、创建背景框的资源文件,list_text_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <stroke
            android:width="1dp"
            android:color="@color/colorWhite"/>
    </shape>
    

    6、创建下拉按钮的资源文件,slide_button.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_selected="true" android:drawable="@drawable/up"/>
        <item android:state_selected="false" android:drawable="@drawable/down"/>
    </selector>
    

    7、编写activity的布局文件,activity_list.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context=".ListActivity">
    
        <ImageView
            android:id="@+id/list_actionBar_bg"
            android:layout_width="match_parent"
            android:layout_height="64dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:background="@color/colorModel"/>
    
        <ImageView
            android:id="@+id/list_back_bt"
            android:layout_width="25dp"
            android:layout_height="25dp"
            app:layout_constraintBottom_toBottomOf="@+id/list_actionBar_bg"
            app:layout_constraintLeft_toLeftOf="@+id/list_actionBar_bg"
            android:layout_marginLeft="5dp"
            android:layout_marginBottom="7dp"
            android:padding="3dp"
            android:src="@mipmap/back"
            android:onClick="list_backClick"/>
    
        <TextView
            android:id="@+id/list_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="@+id/list_actionBar_bg"
            app:layout_constraintBottom_toBottomOf="@+id/list_actionBar_bg"
            app:layout_constraintRight_toRightOf="@+id/list_actionBar_bg"
            android:layout_marginBottom="5dp"
            android:text="@string/ListActivity_title"
            android:textColor="@color/colorWhite"
            android:textSize="12pt"/>
    
        <ImageView
            android:id="@+id/list_text_bg"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/list_actionBar_bg"
            app:layout_constraintLeft_toLeftOf="parent"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="35dp"
            android:layout_marginRight="35dp"
            android:background="@drawable/list_text_bg"/>
    
        <ImageView
            android:id="@+id/list_slideButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintRight_toRightOf="@+id/list_text_bg"
            app:layout_constraintTop_toTopOf="@+id/list_text_bg"
            app:layout_constraintBottom_toBottomOf="@+id/list_text_bg"
            android:src="@drawable/slide_button"
            android:onClick="list_slideClick"/>
    
        <TextView
            android:id="@+id/list_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="@+id/list_text_bg"
            app:layout_constraintTop_toTopOf="@+id/list_text_bg"
            app:layout_constraintBottom_toBottomOf="@+id/list_text_bg"
            android:paddingLeft="10dp"
            android:paddingRight="20dp"
            android:singleLine="true"
            android:gravity="center_vertical"
            android:textColor="@color/colorWhite"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    8、ListActivity.java:

    import android.graphics.Color;
    import android.graphics.drawable.ColorDrawable;
    import android.os.Bundle;
    import android.os.Message;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewTreeObserver;
    import android.widget.AdapterView;
    import android.widget.ImageView;
    import android.widget.PopupWindow;
    import android.widget.TextView;
    
    import com.baoyz.swipemenulistview.SwipeMenu;
    import com.baoyz.swipemenulistview.SwipeMenuCreator;
    import com.baoyz.swipemenulistview.SwipeMenuItem;
    import com.baoyz.swipemenulistview.SwipeMenuListView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ListActivity extends FatherActivity implements MyHandler.InMyHandler {//实现MyHandler接口
    
        ImageView textBgImageView;//背景框
        TextView textView;//显示文本
        ImageView slideButton;//下拉按钮
        private String[] devices = {"device1","device2","device3","device4","device5","device6",
                "device7","device8","device9","device10"};//数据源
        List<ListModel> lists;
        SwipeMenuListView swipeMenuListView;//swipeMenuListView
        PopupWindow popupWindow;
        View layoutView;
        CustomListAdapter customListAdapter;//适配器
        MyHandler myHandler;//自定义的Handler
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_list);
    
            myHandler = MyHandler.getInstance();//初始化MyHandler
            myHandler.setInMyHandler(this);//注册接口
    
            initView();
        }
    
        private void initView(){
            //加载button
            slideButton = findViewById(R.id.list_slideButton);
            slideButton.setSelected(false);
            //加载背景框
            textBgImageView = findViewById(R.id.list_text_bg);
            //加载文本控件
            textView = findViewById(R.id.list_text);
            textView.setText(devices[0]);
    
            //加载swipeMenuListView的布局文件
            layoutView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.drop_down_listview, null);
            //获取swipeMenuListView
            swipeMenuListView = layoutView.findViewById(R.id.drop_down_listView);
            //封装数据源
            lists = new ArrayList<>();
            for (String str:devices) {
                ListModel model = new ListModel(str);
                lists.add(model);
            }
            customListAdapter = new CustomListAdapter(this,lists);
            swipeMenuListView.setAdapter(customListAdapter);
    
            SwipeMenuCreator creator = new SwipeMenuCreator() {
                @Override
                public void create(SwipeMenu menu) {//创建侧滑菜单
                    //侧滑菜单的删除按钮
                    SwipeMenuItem delete_item = new SwipeMenuItem(getApplicationContext());
                    delete_item.setBackground(new ColorDrawable(Color.RED));
                    delete_item.setWidth(GeneralFunction.dpToPx(ListActivity.this,90));
                    delete_item.setTitle("Delete");
                    delete_item.setTitleSize(16);
                    delete_item.setTitleColor(Color.WHITE);
                    menu.addMenuItem(delete_item);
                }
            };
            //将侧滑菜单添加到ListView里
            swipeMenuListView.setMenuCreator(creator);
            //ListView添加侧滑监听
            swipeMenuListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
                    //index的值就是在SwipeMenu依次添加SwipeMenuItem顺序值,类似数组的下标。
                    //从0开始,依次是:0、1、2、3...
                    switch (index) {
                        case 0:
                            swipeMenuListView.smoothCloseMenu();
                            Message message = new Message();
                            message.what = position;
                            //这里设置延时是因为ListView刷新需要时间
                            myHandler.sendMessageDelayed(message, 500);
                            break;
                        default:
                            break;
                    }
                    // false : 当用户触发其他地方的屏幕时候,自动收起菜单。
                    // true : 不改变已经打开菜单的样式,保持原样不收起。
                    return false;
                }
            });
    
            // 监测用户在ListView的SwipeMenu侧滑事件。
            swipeMenuListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
                @Override
                public void onSwipeStart(int pos) {
    //                Log.d("位置:" + pos, "开始侧滑...");
                }
                @Override
                public void onSwipeEnd(int pos) {
    //                Log.d("位置:" + pos, "侧滑结束.");
                }
            });
    
            //点击listView的item事件处理
            swipeMenuListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    popupWindow.dismiss();//使PopupWindow消失
                    slideButton.setSelected(false);
                    ListModel model = lists.get(position);
                    textView.setText(model.deviceName);
                }
            });
    
            //注册一个ViewTreeObserver的监听回调专门监听绘图,因为控件是在OnCreate()事件之后才加载完成
            //通过监听绘图我们就可以获取控件的测量值了,我们必须在每次监听前都remove前一次的监听,避免重复监听
            ViewTreeObserver vto = textBgImageView.getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    textBgImageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);//移除监听
    
                    //考虑到textView可能内容过长,所以这里计算布局,给予textView固定宽度和高度
                    int textViewWidth = textBgImageView.getWidth()-slideButton.getWidth();
                    textView.setWidth(textViewWidth);
                    textView.setHeight(textBgImageView.getHeight());
    
                    //获取editText的坐标
                    int[] location = new int[2];
                    textBgImageView.getLocationOnScreen(location);
                    int x = location[0];
                    int y = location[1];
                    //获取屏幕高度
                    int screenHeight = GeneralFunction.getRealScreenHeight(ListActivity.this);
                    //计算得出listView的可用高度
                    int listHeight = screenHeight-y-textBgImageView.getHeight();
    
                    //初始化PopupWindow
                    popupWindow = new PopupWindow(ListActivity.this);
                    //设置宽高
                    popupWindow.setHeight((listHeight-35)/2);
                    popupWindow.setWidth(textBgImageView.getWidth());
                    //将装载着listView的view添加到PopupWindow里
                    popupWindow.setContentView(layoutView);
                    //使PopupWindow可点击
                    popupWindow.setTouchable(true);
                    popupWindow.setBackgroundDrawable(getDrawable(R.color.colorWhite));
                }
            });
    
        }
    
        //实现MyHandler的接口方法
        @Override
        public void InHandleMessage(Message message) {
            int position = message.what;
            lists.remove(position);//接收Handler发送的消息,删除数据
            customListAdapter.notifyDataSetChanged();//刷新数据源
        }
    
        //返回按钮点击事件
        public void list_backClick(View view){
            finish();
        }
    
        //slideButton点击事件
        public void list_slideClick(View view){
            if(slideButton.isSelected()){
                slideButton.setSelected(false);
                popupWindow.dismiss();//隐藏popupWindow
            }else {
                slideButton.setSelected(true);
                popupWindow.showAsDropDown(textBgImageView);//显示popupWindow
            }
        }
    
    }
    

    9、自定义的Handler类,MyHandler.java:

    import android.os.Handler;
    import android.os.Message;
    
    /**
     * Handler单例的封装
     */
    public class MyHandler extends Handler {
        private MyHandler(){}
        private static class MyHandlerHolder{
            private static final MyHandler INSTANCE = new MyHandler();
        }
        static MyHandler getInstance(){
            return MyHandlerHolder.INSTANCE;
        }//返回线程安全的单例
    
        @Override
        public void handleMessage(Message message){//重写handleMessage方法
            super.handleMessage(message);
            if (inMyHandler!=null){
                inMyHandler.InHandleMessage(message);//调用接口方法
            }
        }
    
        private static InMyHandler inMyHandler;//定义接口变量
        public interface InMyHandler{//定义接口
            void InHandleMessage(Message message);//定义接口方法
        }
        void setInMyHandler(InMyHandler inMyHandler){//注册接口的方法
            MyHandler.inMyHandler = inMyHandler;//接口的引用指向它的实例化对象,传入的参数inMyHandler为实现该接口的类的实例化对象
        }
        void removeInMyHandler(){//取消注册接口的方法
            MyHandler.inMyHandler = null;//inMyHandler置为null,inMyHandler将不再持有外部类引用
        }
    
    }
    

    10、集成公共函数的类,GeneralFunction.java:

    import android.content.Context;
    import android.util.DisplayMetrics;
    import android.view.WindowManager;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class GeneralFunction {
        private GeneralFunction(){}
        private static class GeneralFunctionHolder{
            private static final GeneralFunction INSTANCE = new GeneralFunction();
        }
        public static GeneralFunction getInstance(){
            return GeneralFunctionHolder.INSTANCE;
        }
    
        /**
         * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
         */
        public static int dpToPx(Context context, float dpValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    
        /**
         * 获取应用程序显示区域宽高(不包括状态栏)
         */
        static List getScreenInformation(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            List<Integer> list = new ArrayList<>();
            if (windowManager != null) {
                DisplayMetrics outMetrics = new DisplayMetrics();
                windowManager.getDefaultDisplay().getMetrics(outMetrics);
                int widthPixels = outMetrics.widthPixels;//宽度(以像素为单位)。
                int heightPixels = outMetrics.heightPixels;//高度(以像素为单位)。
    //            int densityDpi = outMetrics.densityDpi;//屏幕密度表示为每英寸点数。
    //            float density = outMetrics.density;//显示器的逻辑密度。
    //            float scaledDensity = outMetrics.scaledDensity;//显示屏上显示的字体缩放系数。
                list.add(widthPixels);
                list.add(heightPixels);
                return list;
            }
            return null;
        }
        /**
         * 实际屏幕显示区域宽高
         */
        static List getRealScreenInformation(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            List<Integer> list = new ArrayList<>();
            if (windowManager != null) {
                DisplayMetrics outMetrics = new DisplayMetrics();
                windowManager.getDefaultDisplay().getRealMetrics(outMetrics);
                int widthPixels = outMetrics.widthPixels;//宽度(以像素为单位)。
                int heightPixels = outMetrics.heightPixels;//高度(以像素为单位)。
                list.add(widthPixels);
                list.add(heightPixels);
                return list;
            }
            return null;
        }
    
        /**
         * 获取屏幕高度
         */
        static int getRealScreenHeight(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            int height = 0;
            if (windowManager != null) {
                DisplayMetrics outMetrics = new DisplayMetrics();
                windowManager.getDefaultDisplay().getRealMetrics(outMetrics);
                height = outMetrics.heightPixels;//高度(以像素为单位)。
            }
            return height;
        }
    
        /**
         * 获取屏幕宽度
         */
        static int getRealScreenWidth(Context context) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            int width = 0;
            if (windowManager != null) {
                DisplayMetrics outMetrics = new DisplayMetrics();
                windowManager.getDefaultDisplay().getRealMetrics(outMetrics);
                width = outMetrics.widthPixels;//高度(以像素为单位)。
            }
            return width;
        }
    
    
    }
    

    相关文章

      网友评论

          本文标题:Android 使用PopupWindow和SwipeMenuL

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