Linearlayout管理器+ recyclerview:StackFromEnd(true)仍显示在顶部而不是底部

时间:2018-09-30 09:38:25

标签: android

我是androidstudio / java编程的新手,所以我正在寻求帮助。我目前正在尝试使用Firebase和Android Studio制作类似于Facebook Messenger的应用程序。我正在尝试为ChatActivity创建布局的阶段(请参见下面的代码)。但是,在屏幕底部显示新消息时遇到一些问题。

我尝试使用“ .setStackFromEnd(true);”但是将其设置为true或false,文本仍会显示在顶部! (查看图片)

代码:

ChatActivity如下:

public class ChatActivity extends AppCompatActivity {

//Firebase variables
private FirebaseAuth mAuth;
private DatabaseReference mDatabaseUser, mDatabaseChat;
private FirebaseStorage mStorage;
private StorageReference mStorageReference;


//Recyclerview variables
private RecyclerView recyclerView;
private RecyclerViewChatAdapter mChatAdapter;



//Variables for users
private String userId,friendId,namefriend,chatId;
private CircleImageView mImageFriend;
private ArrayList<ChatObject> resultsChat = new ArrayList<>();

private Button mSendButton;
private EditText mSendText;
private TextView mNameFriend;

//Linear layout manager
private LinearLayoutManager mLayoutManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);



    //prevent opening keyboard automatically
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);


    //Set firebase variables
    mAuth = FirebaseAuth.getInstance();
    userId = mAuth.getCurrentUser().getUid();
    friendId = getIntent().getExtras().getString("friendId");
    namefriend = getIntent().getExtras().getString("friendName");
    mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("Friends").child(userId).child("Friendlist").child(friendId).child("chatId");
    mDatabaseChat = FirebaseDatabase.getInstance().getReference();
    mStorage = FirebaseStorage.getInstance();
    mStorageReference = mStorage.getReference();


    //Get findviewbyId's
    recyclerView = (RecyclerView) findViewById(R.id.ChatActivity_recyclerview);
    mSendButton = (Button) findViewById(R.id.ChatActivity_Send);
    mSendText = (EditText) findViewById(R.id.ChatActivity_SendText);
    mNameFriend = (TextView) findViewById(R.id.ChatActivity_Name);
    mImageFriend = (CircleImageView) findViewById(R.id.ChatActivity_ImageFriend);


    //Filling in recyclerview and adapter
    FillInRecyclerView();


    //Set name
    mNameFriend.setText("  "+namefriend);
    //set picture
    StorageReference profileRef = mStorageReference.child("profilepictures/"+friendId);
    GlideApp.with(this)
            .load(profileRef)
            .into(mImageFriend);

    //Setting database for messages
    getChatId();

    //Send message
    mSendButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            sendMessage();
        }
    });




}

private void sendMessage() {
        String sendMessageText = mSendText.getText().toString();
        if(!sendMessageText.isEmpty()){
            DatabaseReference newMessageDb = mDatabaseChat.push();
            Map newMessage = new HashMap();
            newMessage.put("createdByUser", userId);
            newMessage.put("text", sendMessageText);
            newMessageDb.setValue(newMessage);
        }
    mSendText.setText(null);
}

private void getChatId(){
    mDatabaseUser.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists()){
                chatId = dataSnapshot.getValue().toString();
                mDatabaseChat =  mDatabaseChat.child("Message").child(chatId);
                getChatMessages();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}


private void getChatMessages() {
    mDatabaseChat.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            if(dataSnapshot.exists()){
                String message = null;
                String createdByUser = null;

                if (dataSnapshot.child("text").getValue()!=null){
                    message = dataSnapshot.child("text").getValue().toString();
                }

                if (dataSnapshot.child("createdByUser").getValue()!=null){
                    createdByUser = dataSnapshot.child("createdByUser").getValue().toString();
                }


                if(message!=null && createdByUser!=null){
                    Boolean currentUserBoolean = false;
                    if(createdByUser.equals(userId)){
                        currentUserBoolean=true;
                    }

                    ChatObject newMessage = new ChatObject(message, currentUserBoolean, createdByUser);
                    resultsChat.add(0,newMessage);
                    mChatAdapter.notifyDataSetChanged();
                    mLayoutManager.scrollToPositionWithOffset(0,0);

                }


            }
        }

        @Override
        public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });
}


public void FillInRecyclerView(){
    mLayoutManager = new LinearLayoutManager(this);
    recyclerView.setNestedScrollingEnabled(false);
    recyclerView.setHasFixedSize(true);

    mLayoutManager.setReverseLayout(true);
    mLayoutManager.setStackFromEnd(true);
    mLayoutManager.scrollToPositionWithOffset(0,0);

    mChatAdapter = new RecyclerViewChatAdapter(ChatActivity.this, resultsChat);
    recyclerView.setAdapter(mChatAdapter);


    recyclerView.setLayoutManager(mLayoutManager);


}

ActivityChat XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ChatActivity">

    <LinearLayout
        android:id="@+id/ChatActivity_LinearLayoutHeader"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="@drawable/background_chatheader"
        android:paddingStart="7dp"
        android:paddingLeft="7dp"
        android:windowSoftInputMode="adjustResize"
        android:layout_marginBottom="3dp">

        <de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:id="@+id/ChatActivity_ImageFriend"
            android:src="@mipmap/ic_launcher"
            android:layout_gravity="center"
            />

    <TextView
        android:id="@+id/ChatActivity_Name"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="Test"
        android:gravity="center_vertical|start"
        android:textSize="25sp"

        android:textColor="@color/white"
        android:fontFamily="sans-serif"

      />
    </LinearLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_below="@+id/ChatActivity_LinearLayoutHeader"
        android:layout_above="@id/ChatActivity_LinearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:overScrollMode="never"
        android:scrollbarStyle="outsideOverlay"
        >

        <android.support.v7.widget.RecyclerView
            app:stackFromEnd="true"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/ChatActivity_LinearLayout"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager"
            android:id="@+id/ChatActivity_recyclerview"
          >

        </android.support.v7.widget.RecyclerView>



    </android.support.v4.widget.NestedScrollView>

    <LinearLayout
        android:id="@+id/ChatActivity_LinearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">


        <EditText
            android:layout_weight="0.7"
            android:id="@+id/ChatActivity_SendText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:hint="Type your message..."
            />

        <Button
            android:layout_weight="0.3"
            android:id="@+id/ChatActivity_Send"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="send"/>

    </LinearLayout>



</RelativeLayout>

recyclerview的Itemlayout xml文件:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/Recyclerview_Parent_Container"
    >

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/Recyclerview_ChatImage"
        android:layout_width="42dp"
        android:layout_height="42dp"
        android:src="@mipmap/ic_launcher"
        android:visibility="invisible"
         />


    <LinearLayout
        android:layout_marginStart="9dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="6sp"
        android:id="@+id/Recyclerview_Container"
        android:orientation="horizontal"
        android:background="@drawable/border_chat_bubbles"
        android:layout_marginLeft="7dp"
        android:layout_marginEnd="7dp">



        <TextView

            android:id="@+id/Recyclerview_Message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Text"
            android:textSize="18sp"

            />

    </LinearLayout>

</LinearLayout>

RecyclerView适配器代码:

public class RecyclerViewChatAdapter extends RecyclerView.Adapter<RecyclerViewChatAdapter.ViewHolder> {

private List<ChatObject> chatList;
private Context context;

//Firebase
private FirebaseAuth mAuth;
private String CurrentUserId;
private FirebaseStorage mStorage;
private StorageReference mStorageReference;

public RecyclerViewChatAdapter(Context context, List<ChatObject> chatList) {
    this.chatList = chatList;
    this.context = context;
}


@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerview_chatlist_layout, viewGroup, false);
    ViewHolder holder = new ViewHolder(view);
    return holder;
}


@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {


    //Firebase variables
    mStorage = FirebaseStorage.getInstance();
    mStorageReference = mStorage.getReference();
    mAuth = FirebaseAuth.getInstance();
    CurrentUserId = mAuth.getCurrentUser().getUid();

    //Setting profile picture into recyclerview
    StorageReference profileRef = mStorageReference.child("profilepictures/" + chatList.get(position).getUserid());
    GlideApp.with(context)
            .load(profileRef)
            .into(holder.mProfilepicture);


    //Setting message layout for user and friend
    holder.mMessage.setText(chatList.get(position).getMessage());
    if (chatList.get(position).getCurrentUser()) {
        holder.mParentContainer.setGravity(Gravity.END);
        holder.mMessage.setTextColor(Color.parseColor("#404040"));
        holder.mContainer.setBackgroundResource(R.drawable.border_chat_bubbles);
        holder.mProfilepicture.setVisibility(View.INVISIBLE);
    } else {
        holder.mParentContainer.setGravity(Gravity.START);
        holder.mMessage.setTextColor(Color.parseColor("#FFFFFF"));
        holder.mContainer.setBackgroundResource(R.drawable.border_chat_bubbles_friend);
        holder.mProfilepicture.setVisibility(View.VISIBLE);


        //Set picture of friend when multiple messages
        int i = 1;
        if(position+i<chatList.size()) {
            while (!chatList.get(position + i).getCurrentUser()) {
                if ((chatList.get(position + i).getCurrentUser()) == chatList.get(position).getCurrentUser()) {
                    holder.mProfilepicture.setVisibility(View.INVISIBLE);
                    i++;
                } else {
                    break;
                }
                if (position + i == chatList.size()) {
                    break;
                }
            }

        }
    }

}

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

public class ViewHolder extends RecyclerView.ViewHolder {
    TextView mMessage;
    LinearLayout mContainer, mParentContainer;
    CircleImageView mProfilepicture;


    public ViewHolder(View itemView) {
        super(itemView);
        mParentContainer = itemView.findViewById(R.id.Recyclerview_Parent_Container);
        mMessage = itemView.findViewById(R.id.Recyclerview_Message);
        mContainer = itemView.findViewById(R.id.Recyclerview_Container);
        mProfilepicture = itemView.findViewById(R.id.Recyclerview_ChatImage);

    }
}

在模拟器上的外观:

Screenshot of emulator of what it looks like

我希望它看起来像什么

Emulator of what I want

现在,如果我将SetStackFromEnd设置为true或false,我将得到与上图相同的结果。但是,SetReverseLayout确实可以工作!也不起作用的是scrollToPositionWithOffset(0,0);或其他任何变体形式,我认为该问题必须相互关联

我已经尝试做些什么,但是没用:

  • 在调用“ FillInRecyclerView()”方法的时间更改位置,但这没有任何改变。

  • SetReverseLayout / SetStackFromEnd到true的各种组合

  • 在XML代码中将stackfromend设置为true
  • 在“ ChatActivity.xml”中将RelativeLayout更改为LinearLayout
  • 设置相对布局高度以匹配父级

欢迎任何帮助!

谢谢

1 个答案:

答案 0 :(得分:1)

您需要同时使用setStackFromEnd和setReverseLayout。将两个值都设置为true,您将获得预期的输出。

    LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(mContext);
    recyclerView.setLayoutManager(mLinearLayoutManager);
    mLinearLayoutManager.setStackFromEnd(true);
    mLinearLayoutManager.setReverseLayout(true);