【问题标题】:Scroll to bottom in recyclerview with multiple view types在具有多种视图类型的回收器视图中滚动到底部
【发布时间】:2017-09-25 18:12:25
【问题描述】:

我有一个包含多个项目的回收站视图。并且recyclerview有不同的viewtypes不同的高度..

这些都是我尝试过的

recyclerview.scrollToPosition(adapterWrapper.getAdapter().getItemCount()-1);

app:layoutManager="LinearLayoutManager"
app:stackFromEnd="true"

当我仅将它们应用于单视图类型时,它们对我很有效。但在多视图类型中。它没有滚动到底部。它被卡在底部之前的 9 个项目上。

我之前在列表视图中使用stackFromBottom,它工作正常..

那么在recyclerview有什么解决办法呢?

它实际上是一个聊天应用程序,具有不同类型的布局,包括图像、gif 等。

RecyclerAdapter 代码,

package com.buckydroid.anonchat.Adapters;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.URLUtil;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;

import com.buckydroid.anonchat.Async.DownloadManager;
import com.buckydroid.anonchat.Chatroom.ChatRoom;
import com.buckydroid.anonchat.Pages.FullScreenImageView;
import com.buckydroid.anonchat.Pages.Profile;
import com.buckydroid.anonchat.Pages.VideoPlayer;
import com.buckydroid.anonchat.R;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
import com.bumptech.glide.request.target.Target;
import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.vanniktech.emoji.EmojiTextView;

import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import de.hdodenhof.circleimageview.CircleImageView;

/**
 * Created by buckydroid on 27/04/17.
 */

public class ChatRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    List<String> message = new ArrayList<>();
    List<Integer> image = new ArrayList<>();
    List<String> usernames = new ArrayList<>();
    List<String> keys = new ArrayList<>();
    ChatRoom chatroom = new ChatRoom();
    String name;
    Context c;
    String username;
    String otherusername;
    String groupName;
    public GifDrawable gifDrawable;
    List<Integer> type = new ArrayList<>();
    String id;
    ArrayList<String> zcode = new ArrayList<>();

    public ChatRecyclerAdapter(String id, String s, List<String> message, List<Integer> image, Context c, String username, String otherusername, List<Integer> type, List<String> usernames, String j, ArrayList<String> zcode) {
        this.message = message;
        this.image = image;
        this.c = c;
        this.username = username;
        this.otherusername = otherusername;
        this.type = type;
        this.usernames = usernames;
        this.groupName = j;
        this.name = s;
        this.id = id;
        this.zcode = zcode;

    }


    class ViewHolder extends  RecyclerView.ViewHolder{
        ImageView imageView;
        EmojiTextView messageView;
        CircleImageView profileImage;
        ImageView gif;
        TextView groupactionmessage;
        ImageView thumbnail;
        TextView filename;
        TextView filesize;
        TextView morevert;
        public ViewHolder(View itemView) {
            super(itemView);
            messageView = (EmojiTextView) itemView.findViewById(R.id.message_view);
            imageView = (ImageView) itemView.findViewById(R.id.imageMessage);
            profileImage = (CircleImageView) itemView.findViewById(R.id.profile_image);
            thumbnail = (ImageView) itemView.findViewById(R.id.thumbnail);
            filename = (TextView) itemView.findViewById(R.id.filename);
            gif = (ImageView) itemView.findViewById(R.id.gifmessage);
            groupactionmessage = (TextView) itemView.findViewById(R.id.group_action_message);


        }
    }



    @Override
    public int getItemViewType(int position) {
        if (username.equals(usernames.get(position))) {
            Log.i("type", String.valueOf(type.get(position)));
            return type.get(position);
        }
        else
            return type.get(position)+7;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = null;
        switch (viewType){

            case 0:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.sender_message_bubble, parent, false);
                System.out.println("Type 0");
                return new ViewHolder(v);


            case 7:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.message_item, parent, false);;
                System.out.println("Type 7");
                return new ViewHolder(v);


            case 1:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.sender_image_layout, parent, false);
                System.out.println("Type 1");
                return new ViewHolder(v);


            case 8:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.chatroom_image, parent, false);
                System.out.println("Type 8");
                return new ViewHolder(v);
            case 2:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.sender_gif, parent, false);
                System.out.println("Type 2");
                return new ViewHolder(v);


            case 9:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.chatroom_gif, parent, false);
                System.out.println("Type 9");

            case 3:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.group_actions_list, parent, false);
                System.out.println("Type 3");
                return new ViewHolder(v);


            case 10:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.group_actions_list, parent, false);
                System.out.println("Type 10");
                return new ViewHolder(v);


            case 4:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.video_thumbnail_message, parent, false);
                System.out.println("Type 4");
                return new ViewHolder(v);

            case 11:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.video_thumbnail_message2, parent, false);
                System.out.println("Type 11");
                return new ViewHolder(v);

            case 5:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.file_layout, parent, false);
                System.out.println("Type 5");
                return new ViewHolder(v);

            case 12:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.sender_file_layout, parent, false);
                System.out.println("Type 12");
                return new ViewHolder(v);

            default:
                v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.message_item, parent, false);
                return new ViewHolder(v);

        }




    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (holder.getItemViewType()){
            case 0:
            case 7:

                Log.i("Type on message", String.valueOf(type.get(position)) + "  " +message.get(position) + "   "+holder.getItemViewType());

                ViewHolder messageHolder = (ViewHolder)holder;
                if (!username.equals(usernames.get(position)))
                    messageHolder.profileImage.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent i = new Intent(c, Profile.class);
                            i.putExtra("username",usernames.get(position));
                            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            c.startActivity(i);
                        }
                    });
                Firebase userdata = new Firebase("https://droidchatz.firebaseio.com/userdata/"+usernames.get(position));
                userdata.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (!usernames.get(position).equals(username))
                            Glide.with (c.getApplicationContext())
                                    .load (dataSnapshot.child("pic").getValue(String.class))
                                    .diskCacheStrategy(DiskCacheStrategy.ALL)

                                    .error (R.drawable.dog)
                                    .into (messageHolder.profileImage);

                    }

                    @Override
                    public void onCancelled(FirebaseError firebaseError) {

                    }
                });

               messageHolder.messageView.setText(message.get(position));




                messageHolder.messageView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        PopupMenu popupMenu = new PopupMenu(c, messageHolder.messageView);
                        popupMenu.getMenuInflater().inflate(R.menu.messsage_popup_menu, popupMenu.getMenu());
                        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                            @Override
                            public boolean onMenuItemClick(MenuItem item) {
                                switch (item.getItemId()) {
                                    case R.id.action_reply:
                                        String te = usernames.get(position) + " : " + messageHolder.messageView.getText() + "\n\n\n";
                                        ChatRoom.input.setText(te);
                                        ChatRoom.input.setSelection(te.length());
                                        break;
                                    case R.id.action_copy:
                                        android.content.ClipboardManager clipboard = (android.content.ClipboardManager) c.getSystemService(Context.CLIPBOARD_SERVICE);
                                        android.content.ClipData clip = android.content.ClipData.newPlainText(messageHolder.messageView.getText(), messageHolder.messageView.getText());
                                        clipboard.setPrimaryClip(clip);
                                        Toast.makeText(c, "Text Copied...", Toast.LENGTH_SHORT).show();
                                        break;
                                    case R.id.action_report:
                                        new Firebase("https://droidchatz.firebaseio.com/groupchat/" + name).child("report").child(usernames.get(position)).child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(true);

                                        break;

                                }
                                return false;
                            }
                        });
                        popupMenu.show();
                        return false;
                    }
                });

                break;





            case 1:
            case 8:
                ViewHolder imageHolder = (ViewHolder)holder;

                Log.i("Type on image", String.valueOf(type.get(position)) + "  " +message.get(position)+"   "+holder.getItemViewType());

                imageHolder.imageView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent i = new Intent(c, FullScreenImageView.class);
                        i.putExtra("uri", message.get(position));
                        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        c.startActivity(i);
                    }
                });



                imageHolder.imageView.setAdjustViewBounds(true);
                GlideDrawableImageViewTarget imageViewPreview = new GlideDrawableImageViewTarget(imageHolder.imageView);
                Glide
                        .with(c)
                        .load(message.get(position))
                        .centerCrop()
                        .listener(new RequestListener<String, GlideDrawable>() {
                            @Override
                            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                                return false;
                            }

                            @Override
                            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                                return false;
                            }
                        })
                        .into(imageViewPreview);

                Firebase userdata2 = new Firebase("https://droidchatz.firebaseio.com/userdata/"+usernames.get(position));
                userdata2.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (!usernames.get(position).equals(username)) {
                            Glide.with (c)
                                    .load (dataSnapshot.child("pic").getValue(String.class))
                                    .error (R.drawable.dog)
                                    .into (imageHolder.profileImage);


                        }                }

                    @Override
                    public void onCancelled(FirebaseError firebaseError) {

                    }
                });




                break;
            case 2:
            case 9:

                Log.i("Type on gif", String.valueOf(type.get(position)) + "  " +message.get(position)+"   "+holder.getItemViewType());

                ViewHolder gifHolder = (ViewHolder)holder;
                gifHolder.gif.setAdjustViewBounds(true);
                GlideDrawableImageViewTarget imageViewPreview2 = new GlideDrawableImageViewTarget(gifHolder.gif);
                Glide
                        .with(c)
                        .load(message.get(position))
                        .listener(new RequestListener<String, GlideDrawable>() {
                            @Override
                            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                                return false;
                            }

                            @Override
                            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                                return false;
                            }
                        })
                        .into(imageViewPreview2);
                if (!username.equals(usernames.get(position)))
                    gifHolder.profileImage.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent i = new Intent(c, Profile.class);
                            i.putExtra("username",usernames.get(position));
                            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            c.startActivity(i);
                        }
                    });


                Firebase userdata3 = new Firebase("https://droidchatz.firebaseio.com/userdata/"+usernames.get(position));
                userdata3.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (!usernames.get(position).equals(username))
                            Glide.with (c)
                                    .load (dataSnapshot.child("pic").getValue(String.class))
                                    .error (R.drawable.dog)
                                    .into (gifHolder.profileImage);

                    }

                    @Override
                    public void onCancelled(FirebaseError firebaseError) {

                    }
                });


                break;
            case 3:
            case 10:
                Log.i("Type on action", String.valueOf(type.get(position)) + "  " +message.get(position)+"   "+holder.getItemViewType());

                ViewHolder actionHolder = (ViewHolder)holder;
                actionHolder.groupactionmessage.setText(message.get(position));


                break;

            case 4:
            case 11:

                ViewHolder videoHolder = (ViewHolder)holder;
                Log.i("Type on video", String.valueOf(type.get(position)) + "  " +message.get(position)+"   "+holder.getItemViewType());
                FirebaseDatabase.getInstance().getReference().child("thumbnails").child(name).child(zcode.get(position)).addValueEventListener(new com.google.firebase.database.ValueEventListener() {
                    @Override
                    public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
                        Glide.with(c).load(dataSnapshot.getValue(String.class)).centerCrop().into(videoHolder.thumbnail);
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });


                if (!username.equals(usernames.get(position)))
                    videoHolder.profileImage.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent i = new Intent(c, Profile.class);
                            i.putExtra("username",usernames.get(position));
                            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            c.startActivity(i);
                        }
                    });
                videoHolder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent i = new Intent(c, VideoPlayer.class);
                        i.putExtra("link", message.get(position));
                        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        c.startActivity(i);

                    }
                });
                Firebase userdata4 = new Firebase("https://droidchatz.firebaseio.com/userdata/"+usernames.get(position));

                userdata4.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (!usernames.get(position).equals(username))
                            Glide.with (c)
                                    .load (dataSnapshot.child("pic").getValue(String.class))
                                    .error (R.drawable.dog)
                                    .into (videoHolder.profileImage);

                    }

                    @Override
                    public void onCancelled(FirebaseError firebaseError) {

                    }
                });



                break;
            case 5:
            case 12:



                ViewHolder fileHolder = (ViewHolder)holder;
                Firebase userdata5 = new Firebase("https://droidchatz.firebaseio.com/userdata/"+usernames.get(position));
                if (!username.equals(usernames.get(position)))
                    fileHolder.profileImage.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Intent i = new Intent(c, Profile.class);
                            i.putExtra("username",usernames.get(position));
                            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            c.startActivity(i);
                        }
                    });
                userdata5.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (!usernames.get(position).equals(username))

                            Glide.with (c)
                                    .load (dataSnapshot.child("pic").getValue(String.class))
                                    .error (R.drawable.dog)
                                    .into (fileHolder.profileImage);

                    }

                    @Override
                    public void onCancelled(FirebaseError firebaseError) {

                    }
                });
                fileHolder.filename.setText(URLUtil.guessFileName(message.get(position), null, null));
                final URL[] uri = new URL[1];
                final URLConnection[] ucon = new URLConnection[1];
                final String[] contentLengthStr = new String[1];
                Thread size = new Thread();
                Runnable getfilesize;
                fileHolder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(message.get(position)));
                        c.startActivity(browserIntent);
                    }
                });
                break;


        }




    }



    @Override
    public int getItemCount() {
        return message.size();
    }


    }

谢谢!!!

【问题讨论】:

  • 你在哪里调用这个方法?recyclerview.scrollToPosition(adapterWrapper.getAdapter().getItemCount()-1);试试这个 mRecyclerView.post(new Runnable() { @Override public void run() { mRecyclerView.scrollToPosition(mData.size()-1); } });
  • @ReyanshMishra 我在 oncreate 中尝试了 setStackFromEnd。 recyclerview.setAdapter 之后的 ScrollToPostion
  • 一旦你的所有数据都被加载并且你的 recyclerview 和适配器准备好了,那么你应该在之前或之间调用这个方法调用可能会混淆 recyclerview 来计算其适配器中项目的大小。试试上面的代码,让我知道。

标签: java android admob android-recyclerview


【解决方案1】:

您能否向我们展示您的 recyclerview 及其适配器的完整代码。

也许这会起作用

recyclerview.scrollToPosition(mData.size()-1);

其中 mData 是您传递给 recyclerview 适配器的列表 很难弄清楚这么少的代码有什么问题。

【讨论】:

  • 添加了适配器类。而且我不能分享整个活动代码,因为它有 4000 多行......
  • 试过这个解决方案stackoverflow.com/questions/26580723/… 吗?
  • 是的,正如我所说,我尝试了 setstackfromend 它不工作.. 可能这是某种方式工作。让我举个例子。我有 100 个列表项.. 底部滚动停止在 94
  • Imo,mData.size() - 1 是滚动到的正确位置。
【解决方案2】:

我不知道原因,但是我将我的 RecyclerView 高度更改为match_parent 并且它工作正常。

它正在滚动到底部,我仍在使用相同的功能.setstacktoend(true)

感谢所有试图帮助我的人:)

【讨论】:

  • 你成就了我的一天。 Tks
  • 您在 recyclerview 或什么上设置了 setstacktoend(true)?但对我来说不知道这个功能,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2016-09-22
  • 1970-01-01
相关资源
最近更新 更多