单击按钮后如何从浮动的相应 recyclerview 项目中获取相应的文本和图像?

How to get respective text and image from the respective recyclerview item in floaty upon clicking a button?

我正在从 Firebase 中检索一些数据并使用 RecyclerView 显示它。

我的 RecyclerView 中有卡片,其中的文本和图像正在检索。

卡片上有一个启动 floaty 的按钮。 floaty 有一个 ImageView 和一个 TextView,其中应显示单击按钮的卡片中的图像和文本。

问题是当点击第一张卡片的那个按钮时,浮动开始并显示来自相应卡片的图像和文本,但是当我按下另一张卡片的按钮启动浮动时,浮动开始但其中未显示相应卡片中的图像和文本。

这是我的代码:

@Override
    public void bindView(final ViewHolder holder) {
        super.bindView(holder);

       holder.progressBar.findViewById(R.id.progressBar_loading_image);
        holder.imageUID.setText(imageUIDh);
        holder.hDescription.setText(hDescription);

        if (imageUIDh != null) {

            holder.progressBar.setVisibility(View.VISIBLE);

            if (imageUIDh.startsWith("https://firebasestorage.googleapis.com/") || imageUIDh.startsWith("content://")) {
                Picasso.with(holder.itemView.getContext()).cancelRequest(holder.homelessImage);
                Picasso.with(holder.itemView.getContext())
                        .load(imageUIDh)
                        .error(R.drawable.ic_warning_black_24dp)
                        .into(holder.homelessImage, new Callback() {
                    @Override
                    public void onSuccess() {
                        holder.progressBar.setVisibility(View.INVISIBLE);
                    }

                    @Override
                    public void onError() {
                        // TODO Auto-generated method stub
                        Toast.makeText(holder.itemView.getContext(), "Error occurred while loading images. Please retry.", Toast.LENGTH_SHORT).show();
                    }
                });



                final View head = LayoutInflater.from(holder.itemView.getContext()).inflate(R.layout.widget_chathead, null);

                final View body = LayoutInflater.from(holder.itemView.getContext()).inflate(R.layout.content_help_request_chat_head, null);

                holder.progressBar2 = (ProgressBar) body.findViewById(R.id.progressBar_loading_image_ch);
                final ImageView hImageInFloaty = (ImageView) body.findViewById(R.id.hImageHF);
                final TextView hDescriptionInFloaty = (TextView) body.findViewById(R.id.hDescriptionHF);

                holder.btn_accept = (Button) holder.itemView.findViewById(R.id.btn_accept);
                holder.btn_accept.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        if (holder.isNetworkAvailable()) {
                            AlertDialog.Builder builder = new AlertDialog.Builder(holder.itemView.getContext());
                            builder.setMessage(R.string.request_accepted_txt);
                            builder.setPositiveButton("Yes button", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {

                                            holder.floaty = Floaty.createInstance(holder.itemView.getContext(), head, body, holder.NOTIFICATION_ID, notification);
                                            holder.floaty.startService();
                                            hDescriptionInFloaty.setText(holder.hDescription.getText().toString());
                                            Picasso.with(holder.itemView.getContext())
                                                    .load(imageUIDh)
                                                    .error(R.drawable.ic_warning_black_24dp)
                                                    .into(hImageInFloaty, new Callback() {
                                                        @Override
                                                        public void onSuccess() {
                                                            holder.progressBar2.setVisibility(View.GONE);
                                                        }

                                                        @Override
                                                        public void onError() {
                                                            // TODO Auto-generated method stub

                                                        }
                                                    });

                                }

                            });
                            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    Toast.makeText(holder.itemView.getContext(), "The help-request has been rejected.", Toast.LENGTH_LONG).show();
                                }
                            });
                            AlertDialog dialog = builder.create();
                            dialog.show();
                        } else {
                            android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(holder.itemView.getContext());
                            builder.setTitle("No internet connection!");
                            builder.setMessage("We need internet connection to navigate you more accurately. Please connect to the internet and then accept the help-request.");
                            builder.setPositiveButton("Open Settings", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    Intent intent = new Intent(Settings.ACTION_SETTINGS);
                                    holder.itemView.getContext().startActivity(intent);
                                }
                            });
                            builder.setNegativeButton("Cancel", null);
                            builder.show();
                        }

                    }
                });

    }

由于漂浮物需要许可,我在获得许可后填充 recyclerview(仅限 Android M 及以上)。这是代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            startFloatyForAboveAndroidL();
        }

这里是tartFloatyForAboveAndroidL():

@TargetApi(Build.VERSION_CODES.M)
    public void startFloatyForAboveAndroidL() {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
            startActivityForResult(intent, PERMISSION_REQUEST_CODE);
        } else {
            recyclerView.setAdapter(fastItemAdapter);
        }
    }

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == REQUEST_CODE){
            mSheetLayout.contractFab();
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (requestCode == PERMISSION_REQUEST_CODE) {
                if (Settings.canDrawOverlays(this)) {
                    recyclerView.setAdapter(fastItemAdapter);
                } else {
                    Spanned message = Html.fromHtml("Please allow this permission, so <b>Floaties</b> could be drawn.");
                    Toast.makeText(this, message, Toast.LENGTH_LONG).show();
                }
            }
        }
    }

尝试 Eric 的回答后的代码:--

protected static class ViewHolder extends RecyclerView.ViewHolder {

        ImageView hImage;
        TextView imageUID, hDescription;
        View head, body;
        Floaty floaty;
        TextView hDescroptionInFloaty;
        ImageView hImageInFloaty;
        Notification notification;
        Button btn_accept;
        ProgressBar progressBar, progressBar2;
        AppCompatButton btnCloseFloaty;
        private static final int NOTIFICATION_ID = 1500;

        public ViewHolder(final View itemView) {
            super(itemView);

            Intent intent = new Intent(itemView.getContext(), HelpRequest.class);
            PendingIntent resultPendingIntent = PendingIntent.getActivity(itemView.getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            notification = Floaty.createNotification(itemView.getContext(), "HumaneHelper", "Floaty has started with homeless's pic and description", R.mipmap.ic_launcher, resultPendingIntent);

            head = LayoutInflater.from(itemView.getContext()).inflate(R.layout.widget_chathead, null);
            // You should not add click listeners to head as it will be overridden, but the purpose of not making head just
            // an ImageView is so you can add multiple views in it, and show and hide the relevant views to notify user etc.
            body = LayoutInflater.from(itemView.getContext()).inflate(R.layout.content_help_request_chat_head, null);

            floaty = Floaty.createInstance(itemView.getContext(), head, body, NOTIFICATION_ID, notification);

            btnCloseFloaty = (AppCompatButton) body.findViewById(R.id.btn_close_floaty);
            btnCloseFloaty.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    floaty.stopService();
                }
            });

            hDescroptionInFloaty = (TextView) body.findViewById(R.id.hDescriptionHF);
            hImageInFloaty = (ImageView) body.findViewById(R.id.hImageHF);

    }

这里是 bindView():

    @Override
        public void bindView(final ViewHolder holder) {
            super.bindView(holder);
    holder.imageUID.setText(imageUIDh);
            holder.hDescription.setText(hDescription);

    if (imageUIDh != null) {

                    holder.progressBar2 = (ProgressBar) holder.body.findViewById(R.id.progressBar_loading_image_ch);

                    holder.btn_accept = (Button) holder.itemView.findViewById(R.id.btn_accept);
   View.OnClickListener() {
                        @Override
                        public void onClick(View view) {

                            if (holder.isNetworkAvailable()) {

                                holder.hDescroptionInFloaty.setText(holder.hDescription.getText().toString());
                                Picasso.with(holder.itemView.getContext())
                                        .load(imageUIDh)
                                        .error(R.drawable.ic_warning_black_24dp)
                                        .into(holder.hImageInFloaty, new Callback() {
                                            @Override
                                            public void onSuccess() {
                                                holder.progressBar2.setVisibility(View.GONE);
                                            }

                                            @Override
                                            public void onError() {
                                                // TODO Auto-generated method stub

                                            }
                                        });
                                Toast.makeText(holder.itemView.getContext(), "updated: " + holder.homelessDescroptionInFloaty.getText(), Toast.LENGTH_LONG).show();

                                AlertDialog.Builder builder = new AlertDialog.Builder(holder.itemView.getContext());
                                builder.setMessage(R.string.request_accepted_txt);
                                builder.setPositiveButton("Navigate me", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {

                                                holder.floaty = Floaty.createInstance(holder.itemView.getContext(), holder.head, holder.body, holder.NOTIFICATION_ID, holder.notification);
                                                holder.floaty.startService();

                                    }

                                });
                                builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        Toast.makeText(holder.itemView.getContext(), "The help-request has been rejected.", Toast.LENGTH_LONG).show();
                                    }
                                });
                                AlertDialog dialog = builder.create();
                                dialog.show();
                            } else {
                                android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(holder.itemView.getContext());
                                builder.setTitle("No internet connection!");
                                builder.setMessage("We need internet connection to navigate you more accurately. Please connect to the internet and then accept the help-request.");
                                builder.setPositiveButton("Open Settings", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        Intent intent = new Intent(Settings.ACTION_SETTINGS);
                                        holder.itemView.getContext().startActivity(intent);
                                    }
                                });
                                builder.setNegativeButton("Cancel", null);
                                builder.show();
                            }

                        }
                    });

                } else {
                    Toast.makeText(holder.itemView.getContext(), "some problem", Toast.LENGTH_SHORT).show();
                }
        }

这里发生了什么问题?我如何才能将点击其按钮的卡片中的文字和图片放入浮动中?

我已经尝试重写您的代码。

  1. 我不知道class imageUIDh,但我猜它是字符串。

  2. imageUIDh 没有在你的代码中定义,所以我不知道你从哪里得到的。但我已将字段 imageUIDh 添加到您的 ViewHolder。您应该在每个 bindView 上更新它。

  3. 一些行应该移到 ViewHolder 的构造函数中

  4. 我已将 ViewHolder 作为标签添加到 btn_accept,因此您可以对所有 ViewHolder 使用一个 clickListener。

  5. 现在代码中的嵌套少了很多 - 阅读、调试和查找问题变得更加容易。 可能问题现在已经解决了

        @Override
        public void bindView(final ViewHolder holder) {
            super.bindView(holder);
    
            holder.progressBar.findViewById(R.id.progressBar_loading_image);
            holder.imageUID.setText(imageUIDh);
            holder.imageUIDh = imageUIDh;
            holder.hDescription.setText(hDescription);
    
            /// THESE 2 LINES SHOULD BE DONE IN HOLDER'S CONSTRUCTOR!!!!!
            holder.btn_accept = (Button) holder.itemView.findViewById(R.id.btn_accept);
            holder.btn_accept.setTag(holder);
    
            if (imageUIDh != null) {
                holder.progressBar.setVisibility(View.VISIBLE);
    
                if (imageUIDh.startsWith("https://firebasestorage.googleapis.com/") || imageUIDh.startsWith("content://")) {
                    doSomethingWithPicaso(imageUIDh, holder.homelessImage);
    
                    /*
                    /// THESE LINES ARE BE MOVED INTO onClick()
                    final View head = LayoutInflater.from(holder.itemView.getContext()).inflate(R.layout.widget_chathead, null);
                    final View body = LayoutInflater.from(holder.itemView.getContext()).inflate(R.layout.content_help_request_chat_head, null);
    
                    final ImageView hImageInFloaty = (ImageView) body.findViewById(R.id.hImageHF);
                    final TextView hDescriptionInFloaty = (TextView) body.findViewById(R.id.hDescriptionHF);
                    */
    
                    holder.btn_accept.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            ViewHolder holder = (ViewHolder) view.getTag();
                            if (holder.isNetworkAvailable()) {
                                showOnNetworkAvailableAlertDialog(view.getContext(), holder.imageUIDh, holder.hDescription.getText().toString());
                            } else {
                               showNoNetworkAlert(view.getContext());
                            }
                        }
                    });
                }
            }
        }
    
        private void doSomethingWithPicaso(String imageUIDh, ImageView target, final HolderView holder){
            final Context context = target.getContext();
            Picasso.with(context).cancelRequest(holder.homelessImage);
            Picasso.with(context)
                    .load(imageUIDh)
                    .error(R.drawable.ic_warning_black_24dp)
                    .into(target, new Callback() {
                        @Override
                        public void onSuccess() {
                            holder.progressBar.setVisibility(View.INVISIBLE);
                        }
    
                        @Override
                        public void onError() {
                            Toast.makeText(context, "Error occurred while loading images. Please retry.", Toast.LENGTH_SHORT).show();
                        }
                    });
        }
    
        private void showOnNetworkAvailableAlertDialog(final Context context, final String imageUIDh, final String descriptionText){
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setMessage(R.string.request_accepted_txt);
            builder.setPositiveButton("Yes button", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
    
                    final View head = LayoutInflater.from(context).inflate(R.layout.widget_chathead, null);
                    final View body = LayoutInflater.from(context).inflate(R.layout.content_help_request_chat_head, null);
    
                    final ImageView hImageInFloaty = (ImageView) body.findViewById(R.id.hImageHF);
                    final TextView hDescriptionInFloaty = (TextView) body.findViewById(R.id.hDescriptionHF);
                    final View progressBar = body.findViewById(R.id.progressBar_loading_image_ch);
    
                    holder.floaty = Floaty.createInstance(context, head, body, holder.NOTIFICATION_ID, notification);
                    holder.floaty.startService();
                    hDescriptionInFloaty.setText(descriptionText);
                    Picasso.with(context)
                            .load(imageUIDh)
                            .error(R.drawable.ic_warning_black_24dp)
                            .into(hImageInFloaty, new Callback() {
                                @Override
                                public void onSuccess() {
                                    progressBar.setVisibility(View.GONE);
                                }
    
                                @Override
                                public void onError() {
                                    // TODO Auto-generated method stub
    
                                }
                            });
    
                }
    
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    Toast.makeText(holder.itemView.getContext(), "The help-request has been rejected.", Toast.LENGTH_LONG).show();
                }
            });
            builder.show();
        }
    
        private void showNoNetworkAlert(final Context context){
            android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(context);
            builder.setTitle("No internet connection!");
            builder.setMessage("We need internet connection to navigate you more accurately. Please connect to the internet and then accept the help-request.");
            builder.setPositiveButton("Open Settings", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    Intent intent = new Intent(Settings.ACTION_SETTINGS);
                    context.startActivity(intent);
                }
            });
            builder.setNegativeButton("Cancel", null);
            builder.show();
        }
    

如果你看一下 Floaty 代码 here。您会注意到它使用了 SingletonPattern。因此,这就是它第一次工作但之后显示不正确数据的原因。一种解决方案是扩展 Floaty class,并添加您自己的 createInstance 方法。方法的主体将是这样的:

public static synchronized Floaty createInstance(Context context, View head, View body, int notificationId, Notification notification, FloatyOrientationListener
        floatyOrientationListener) {
    if (floaty == null) {
        floaty = new Floaty(context, head, body, notificationId, notification, floatyOrientationListener);
    }else {
        floaty.stopService();
        floaty = null;
        floaty = new Floaty(context, head, body, notificationId, notification, floatyOrientationListener);
    }
    return floaty;
}

我希望这能奏效。

方法二

想到的另一种更简单的方法是,只初始化 Floaty 一次。然后只需引用您的 holder 中的 body 并修改 holder 中的 ImageView 和 TextView。