note_38:自定义PopupWindow

24 篇文章 0 订阅

自定义PopupWindow


上下左右弹出来的PopupWindow


界面:

PopList的界面就是一个LinearLayout包着一个ListView
ListView的item的界面就是一个LinearLayout包着一个TextView

字体变色:

当ListView的item在android:state_selected=true的情况下,想改变字体颜色的话
可以在res文件夹下新建一个Android Resource Directory,并且在Resource type的位置选择color。
在color这个文件夹下创建Color Resource File,然后在TextView设置android:textColor="@color/selector_font_color"。

如果想在字体变色的基础上加上走马灯,那就再加上android:ellipsize=“marquee” android:singleLine=“true” android:marqueeRepeatLimit=“marquee_forever”。不过要注意的是,如果文本内容的所占的长度并没有超过TextView可以显示的长度的话,走马灯是不会有效果的,而且走马灯也只有在获得焦点的时候才会起作用。如果在没有焦点的时候也想让走马灯有效果的话,可以自定义TextView一直得到焦点。

selector_font_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#009cff" android:state_selected="true" />
    <item android:color="#8e8e8e" />
</selector>

加动画:

跟上面创建color文件夹基本上是同样的方法,只是在Resource type里面选的不是color而是anim而已。
然后就可以创建自定义动画的xml了:R.anim.anim_pop_from_top, R.anim.anim_pop_from_bottom, R.anim.anim_pop_from_left, R.anim.anim_pop_from_right。


影响宽高的方法: setBackgroundDrawable(), setHeight(), setWidth()。

一定要调用这三个方法,少了哪一个都有可能让PopupWindow的宽高设置无效。
setBackgroundDrawable()可以设置一张透明的,但是一定要设置。
setWidth()setHeight()如果没有明确的大小的话,可以用ViewGroup.LayoutParams.MATCH_PARENT或者ViewGroup.LayoutParams.WRAP_CONTENT

调整宽高的方法: setHeight(), setWidth(), update()。

用了setHeight()setWidth()之后务必要调用update(),否则设置完了也看不到效果、
不要轻易使用getLayoutParams(),因为很有可能会报空。

避免窗体泄露的方法: dismiss()。

在调用PopList的Activity的onDestroy()里面,必须判断PopList有没有dismiss,如果不判断而PopList又没有dismiss()的话就会造成窗体泄露。

监听PopList的点击:

在PopList和Adapter里面分别定义两个回调接口OnPopItemClickListener, OnClickItemListener,在Activity里面监听PopList的回调就可以了。

PopList.java

class PopList extends PopupWindow {
    private static final String TAG = "PopList";

    static final int FROM_TOP = 0;
    static final int FROM_BOTTOM = 1;
    static final int FROM_LEFT = 2;
    static final int FROM_RIGHT = 3;

    private LinearLayout popLayout;
    private ListView layoutList;

    private Context mContext;
    private PopAdapter mAdapter = null;
    private Animation mAnimaton = null;

    PopList(Context context) {
        super(context);
        mContext = context;

        setFocusable(true);
        setTouchable(true);
        setOutsideTouchable(true);

        setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        setWidth(mContext.getResources().getDimensionPixelOffset(R.dimen.dp_390));

        View view = LayoutInflater.from(context).inflate(R.layout.layout_pop_list, null);
        setContentView(view);
        init(view);
    }

    private void init(View view) {
        popLayout = view.findViewById(R.id.pop_layout);
        layoutList = view.findViewById(R.id.layout_list);
        mAdapter = new PopAdapter();
        mAdapter.setOnItemClickListener(new PopAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position, String title) {
                if (onPopItemClickListener != null) {
                    onPopItemClickListener.onPopItemClick(position, title);
                }
            }
        });
    }

    void setData(List<String> list, int select) {
        if (list == null || list.isEmpty()) return;
        mAdapter.setData(list, select);
        layoutList.setAdapter(mAdapter);
    }

    void show(int direction, View anchor, int itemCount) {
        adjustHeight(direction, itemCount);
        update(); // 调整完宽高之后一定要update()
        showAtLocation(anchor, findGravity(direction), 0, 0);
        appendAnimation(direction);
    }

    private void adjustHeight(int direction, int itemCount) {
        if (direction == FROM_TOP || direction == FROM_BOTTOM) {
            if (itemCount > 6) {
                setHeight(mContext.getResources().getDimensionPixelOffset(R.dimen.dp_480));
            } else {
                setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            }
        } else {
            if (itemCount > 10) {
                setHeight(mContext.getResources().getDimensionPixelOffset(R.dimen.dp_800));
            } else {
                setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            }
        }
    }

    private int findGravity(int direction) {
        switch (direction) {
            case FROM_TOP:
                return Gravity.TOP | Gravity.CENTER_HORIZONTAL;

            case FROM_BOTTOM:
                return Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;

            case FROM_LEFT:
                return Gravity.LEFT | Gravity.CENTER_VERTICAL;

            case FROM_RIGHT:
                return Gravity.RIGHT | Gravity.CENTER_VERTICAL;

            default:
                return Gravity.CENTER;
        }
    }

    private void appendAnimation(int direction) {
        if (mAnimaton != null && !mAnimaton.hasEnded()) mAnimaton.cancel();
        mAnimaton = null;
        switch (direction) {
            case FROM_TOP:
                mAnimaton = AnimationUtils.loadAnimation(mContext, R.anim.anim_pop_from_top);
                break;

            case FROM_BOTTOM:
                mAnimaton = AnimationUtils.loadAnimation(mContext, R.anim.anim_pop_from_bottom);
                break;

            case FROM_LEFT:
                mAnimaton = AnimationUtils.loadAnimation(mContext, R.anim.anim_pop_from_left);
                break;

            case FROM_RIGHT:
                mAnimaton = AnimationUtils.loadAnimation(mContext, R.anim.anim_pop_from_right);
                break;
        }
        if (mAnimaton != null) {
            mAnimaton.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    layoutList.smoothScrollToPosition(mAdapter.getLastSelect());
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            popLayout.setAnimation(mAnimaton);
            mAnimaton.start();
        }
    }

    private OnPopItemClickListener onPopItemClickListener;

    public interface OnPopItemClickListener {
        void onPopItemClick(int position, String title);
    }

    void setOnPopItemClickListener(OnPopItemClickListener onPopItemClickListener) {
        this.onPopItemClickListener = onPopItemClickListener;
    }

    public static class PopAdapter extends BaseAdapter {
        private List<String> mListItems;
        private int mLastSelect = 0;

        PopAdapter() {
            mListItems = new ArrayList<>();
        }

        void setData(List<String> list, int select) {
            if (list == null) return;
            if (mListItems == null) mListItems = new ArrayList<>();
            else if (!mListItems.isEmpty()) mListItems.clear();
            mListItems.addAll(list);
            mLastSelect = select;
            notifyDataSetChanged();
        }

        int getLastSelect() {
            return mLastSelect;
        }

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

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

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item_pop_list, parent, false);
                holder = new ViewHolder();
                holder.itemLayout = convertView.findViewById(R.id.item_layout);
                holder.itemText = convertView.findViewById(R.id.item_text);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.itemText.setSelected(mLastSelect == position);
            holder.itemText.setText(mListItems.get(position));
            holder.itemLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mLastSelect == position) return;
                    mLastSelect = position;
                    if (onItemClickListener != null) {
                        onItemClickListener.onItemClick(position, mListItems.get(position));
                    }
                    // 如果没有这句 那么不会执行holder.itemText.setSelected()
                    notifyDataSetChanged();
                }
            });
            return convertView;
        }

        static class ViewHolder {
            LinearLayout itemLayout;
            TextView itemText;
        }

        private OnItemClickListener onItemClickListener;

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

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

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值