showAsDropDown 某款测试机(Android 4.4.4)在RecyclerView item中显示异常问题

Posted 彼岸花you

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了showAsDropDown 某款测试机(Android 4.4.4)在RecyclerView item中显示异常问题相关的知识,希望对你有一定的参考价值。

popupWindow.showAtLocation 显示在View的上方或者下方

showAsDropDown异常问题

  1. 场景:使用RecyclerView,点击item中的某一个view,需要弹出一个PopupWindow。
  2. 问题:在某一款android 4.4.4的手机上测试,发现,showAsDropDown()显示到了view的上方。在华为meta9上显示正常。
  3. 解决方案:经过测试,showAtLocation 设置的位置是正常的,在下方显示使用showAsDropDown改为showAtLocation。

showAtLocation 位置分析

RecyclerView 点击view 显示popup示例(adapter代码)

默认显示popup在view的下方,在可视范围的最后一个item,点击这个item中的view,显示popup在view的上方。

public class CollegeAdapter extends RecyclerView.Adapter<CollegeAdapter.CollegeHolder> 
    Context context;
    List<CollegeInfo> data;
    private OnCollegeClickListener lis;
    LinearLayoutManager llManager;
    private Window window;

    public CollegeAdapter(Context context, List<CollegeInfo> data, LinearLayoutManager manager) 
        this.context = context;
        this.data = data;
        llManager = manager;
    

    @Override
    public CollegeHolder onCreateViewHolder(ViewGroup parent, int viewType) 
        return new CollegeHolder(LayoutInflater.from(context).inflate(R.layout.item_cardview_college, parent, false));
    

    @Override
    public void onBindViewHolder(final CollegeHolder holder, final int position) 
        CollegeInfo collegeInfo = data.get(position);
        Glide.with(context).load(R.mipmap.msgcontent_adv).transform(new CenterCrop(context), new GlideRoundTransform(context, 6)).into(holder.ivCollege);
        holder.tvTitle.setText(collegeInfo.getTitle());
        holder.tvDes.setText(collegeInfo.getDes());
        holder.tvPrice.setText(collegeInfo.getPrice());
        holder.tvPriceNote.setText(collegeInfo.getPriceNote());
        holder.itemView.setOnClickListener(new OnNoDoubleClickListener() 
            @Override
            public void onNoDoubleClick(View v) 
                if (lis != null) 
                    lis.click(position);
                
            
        );

        holder.vMore.setOnClickListener(new OnNoDoubleClickListener() 
            @Override
            public void onNoDoubleClick(View v) 
                //弹出popupWindow 收藏/分享
                int lastVisibleItemPosition = llManager.findLastVisibleItemPosition();
                showPopup(v, lastVisibleItemPosition == position);
            
        );
    

    /**
     * 是否在上面显示 默认在下面显示
     *
     * @param isUp 是否显示到view的上面
     */
    private void showPopup(View v, boolean isUp) 
        LinearLayout layout = new LinearLayout(context);
        View view = LayoutInflater.from(context).inflate(R.layout.popup_collection, null, false);
        view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        view.setBackgroundResource(isUp ? R.mipmap.ic_popup_up : R.mipmap.ic_popup_down);
        layout.addView(view);

        PopupWindow popupWindow = new PopupWindow(layout, DensityUtils.dp2px(context, 200), DensityUtils.dp2px(context, 99));
        popupWindow.setFocusable(true);
        popupWindow.setOutsideTouchable(true);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        //透明度显示
        window = ((BaseActivity) context).getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.alpha = 0.6f; //0.0-1.0
        window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        window.setAttributes(lp);
        //取消时 不显示透明度
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() 
            @Override
            public void onDismiss() 
                WindowManager.LayoutParams lp = window.getAttributes();
                lp.alpha = 1f;
                window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
                window.setAttributes(lp);
            
        );

        int[] location = new int[2];
        v.getLocationOnScreen(location);

        int x = location[0] + v.getWidth() - popupWindow.getWidth();
        int y = isUp ? location[1] - popupWindow.getHeight() + v.getPaddingTop() : location[1] + v.getHeight() - v.getPaddingBottom();

        popupWindow.showAtLocation(v, Gravity.NO_GRAVITY, x, y);
    

    @Override
    public int getItemCount() 
        return data == null ? 0 : data.size();
    

    class CollegeHolder extends RecyclerView.ViewHolder 

        private final ImageView ivCollege;
        private final TextView tvTitle;
        private final TextView tvDes;
        private final TextView tvPrice;
        private final TextView tvPriceNote;
        private final View vMore;

        CollegeHolder(View itemView) 
            super(itemView);
            ivCollege = itemView.findViewById(R.id.iv_college);
            tvTitle = itemView.findViewById(R.id.tv_title);
            tvDes = itemView.findViewById(R.id.tv_des);
            tvPrice = itemView.findViewById(R.id.tv_price);
            tvPriceNote = itemView.findViewById(R.id.tv_price_note);
            vMore = itemView.findViewById(R.id.iv_more);
        
    

    public interface OnCollegeClickListener 
        void click(int pos);
    

    public void setOnCollegeClickListener(OnCollegeClickListener listener) 
        lis = listener;
    

demo 地址:https://download.csdn.net/download/u012391876/10674452

以上是关于showAsDropDown 某款测试机(Android 4.4.4)在RecyclerView item中显示异常问题的主要内容,如果未能解决你的问题,请参考以下文章

7.0手机后popupWindow 的showAtLocation()和showAsDropDown()

android showAsDropDown的用法属性介绍

android:java.lang.NoSuchMethodError: android.widget.PopupWindow.showAsDropDown

控件PopupWindow

js判断移动端是否安装某款app的多种方法

js判断移动端是否安装某款app的多种方法