我是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
我希望它看起来像什么
现在,如果我将SetStackFromEnd设置为true或false,我将得到与上图相同的结果。但是,SetReverseLayout确实可以工作!也不起作用的是scrollToPositionWithOffset(0,0);或其他任何变体形式,我认为该问题必须相互关联
我已经尝试做些什么,但是没用:
在调用“ FillInRecyclerView()”方法的时间更改位置,但这没有任何改变。
SetReverseLayout / SetStackFromEnd到true的各种组合
欢迎任何帮助!
谢谢
答案 0 :(得分:1)
您需要同时使用setStackFromEnd和setReverseLayout。将两个值都设置为true,您将获得预期的输出。
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(mContext);
recyclerView.setLayoutManager(mLinearLayoutManager);
mLinearLayoutManager.setStackFromEnd(true);
mLinearLayoutManager.setReverseLayout(true);