美文网首页
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