Java 安卓-如何使适配器布局保持原位
我使用Java 安卓-如何使适配器布局保持原位,java,android,Java,Android,我使用firebase创建了一个简单的聊天应用程序,但是在左侧和右侧的位置放置气泡元素时遇到了一点麻烦。左边的泡泡是给别人的,右边的泡泡是给我的 这是我的适配器: public class MessageAdapterCustom extends RecyclerView.Adapter<MessageAdapterCustom.MessageViewHolder> { private List<Messages> mMessageList;
firebase
创建了一个简单的聊天应用程序,但是在左侧和右侧的位置放置气泡元素时遇到了一点麻烦。左边的泡泡是给别人的,右边的泡泡是给我的
这是我的适配器:
public class MessageAdapterCustom extends RecyclerView.Adapter<MessageAdapterCustom.MessageViewHolder> {
private List<Messages> mMessageList;
private Context context;
private String mBubblePosition;
public MessageAdapterCustom(Context context, List<Messages> mMessageList, String mBubblePosition) {
this.context = context;
this.mMessageList = mMessageList;
this.mBubblePosition = mBubblePosition;
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from( parent.getContext() )
.inflate( R.layout.message_single_layout_custom, parent, false );
return new MessageViewHolder( v );
}
public class MessageViewHolder extends RecyclerView.ViewHolder {
public TextView messageText;
public CircleImageView profileImage;
public MessageViewHolder(View view) {
super( view );
if(mBubblePosition.equals( "kiri" )) {
RelativeLayout right = (RelativeLayout) view.findViewById( R.id.sendingMessageLayout );
right.setVisibility( View.GONE );
messageText = (TextView) view.findViewById( R.id.message_text_layout_kiri );
profileImage = (CircleImageView) view.findViewById( R.id.message_profile_layout_kiri );
} else {
LinearLayout left = (LinearLayout) view.findViewById(R.id.recievemessageLayout);
left.setVisibility(View.GONE);
messageText = (TextView) view.findViewById( R.id.message_text_layout_kanan );
profileImage = (CircleImageView) view.findViewById( R.id.message_profile_layout_kanan );
}
}
}
@Override
public void onBindViewHolder(final MessageViewHolder holder, int position) {
final Messages msg = mMessageList.get( position );
holder.messageText.setText( msg.getMessage() );
Picasso.with( context )
.load( msg.getProfile_pic() )
.networkPolicy( NetworkPolicy.OFFLINE )
.into( holder.profileImage );
/*Picasso.with( context )
.load( msg.getProfile_pic() )
.networkPolicy( NetworkPolicy.OFFLINE )
.placeholder( R.drawable.no_profile )
.into( holder.profileImage, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError() {
Picasso.with( context )
.load( msg.getProfile_pic() )
.networkPolicy( NetworkPolicy.OFFLINE )
.into( holder.profileImage );
}
} );*/
}
@Override
public int getItemCount() {
return mMessageList.size();
}
}
当我尝试使用两个设备时,首先如果我自己尝试发送消息,日志会显示右侧
,这意味着气球在右侧上的位置。
但是当我用不同的设备(另一个人)回复时,适配器会将两个气泡移动到左侧。这似乎是因为它遵循最后一个适配器命令。
我的日志
如何在每次消息到达时将适配器保持在适当位置,而不是如图所示更改视图元素的所有结构
--更新--
我的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/stackoverflow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<LinearLayout
android:id="@+id/recievemessageLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/message_profile_layout_kiri"
android:layout_width="55dp"
android:layout_height="55dp"
android:src="@drawable/no_profile" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/message_text_layout_kiri"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:background="@drawable/message_text_background"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:text="@string/message_here"
android:textColor="@android:color/white" />
<ImageView
android:id="@+id/message_buble_kiri"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:layout_marginTop="-10dp"
android:src="@drawable/buble_left" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/sendingMessageLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/recievemessageLayout"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/message_profile_layout_kanan"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_alignParentEnd="true"
android:src="@drawable/no_profile" />
<TextView
android:id="@+id/message_text_layout_kanan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginEnd="10dp"
android:layout_marginTop="5dp"
android:layout_toStartOf="@+id/message_profile_layout_kanan"
android:background="@drawable/message_text_background"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:text="@string/message_here"
android:textColor="@android:color/white" />
<ImageView
android:id="@+id/message_buble_kanan"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignEnd="@+id/message_text_layout_kanan"
android:layout_below="@+id/message_text_layout_kanan"
android:layout_marginTop="-10dp"
android:src="@drawable/buble_right" />
</RelativeLayout>
</RelativeLayout>
您当前正在创建两个不同的适配器,所有消息都指向同一方向。相反,您应该创建一个适配器来决定如何将每条消息一次一条对齐。是否使用多视图类型来循环查看
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class ViewHolder0 extends RecyclerView.ViewHolder {
...
public ViewHolder0(View itemView){
...
}
}
class ViewHolder2 extends RecyclerView.ViewHolder {
...
public ViewHolder2(View itemView){
...
}
@Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
return position % 2 * 2;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 0: return new ViewHolder0(...);
case 2: return new ViewHolder2(...);
...
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolder0 viewHolder0 = (ViewHolder0)holder;
...
break;
case 2:
ViewHolder2 viewHolder2 = (ViewHolder2)holder;
...
break;
}
}
}
公共类MyAdapter扩展了RecyclerView.Adapter{
类ViewHolder0扩展了RecyclerView.ViewHolder{
...
公共视图持有者0(视图项视图){
...
}
}
类ViewHolder2扩展了RecyclerView.ViewHolder{
...
公共视图持有者2(视图项视图){
...
}
@凌驾
public int getItemViewType(int位置){
//例如,根据位置返回0或2
//注意,与ListView适配器不同,类型不必是连续的
返回位置%2*2;
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
开关(视图类型){
案例0:返回新的ViewHolder0(…);
案例2:返回新的ViewHolder2(…);
...
}
}
@凌驾
公共无效onBindViewHolder(最终RecyclerView.ViewHolder,最终整型位置){
开关(holder.getItemViewType()){
案例0:
ViewHolder0 ViewHolder0=(ViewHolder0)holder;
...
打破
案例2:
ViewHolder2 ViewHolder2=(ViewHolder2)支架;
...
打破
}
}
}
您的邮件列表中的项目主要有两种类型:已发送和已接收。您是否可以建立数据模型,以便它们定义其类型,并且在onCreateViewHolder()
中,每种类型都有不同的viewholder。在onBindViewHolder()中
您需要根据项目类型再次绑定视图
我对Naveen的示例进行了一些修改,以获得:
interface MsgType {
int TYPE_SENT = 1;
int TYPE_RECEIVED = 2;
}
class Msg implements MsgType
{
String text ;
int type;
public Msg(String text, int type) {
// set
}
public String getText() {
return text;
}
public int getType() {
return type;
}
}
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<Msg> msgs;
class SentMsgVH extends RecyclerView.ViewHolder {
...
public SentMsgVH(View itemView){
...
}
}
class ReceivedMsgVh extends RecyclerView.ViewHolder {
...
public ReceivedMsgVh(View itemView){
...
}
@Override
public int getItemViewType(int position) {
return msgs.get(position).getType();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType) {
case TYPE_SENT:
v = ... ; // inflate view
return new SentMsgVH(v);
case TYPE_RECEIVED:
v = ...; // inflate view
return new ReceivedMsgVh(v);
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (getItemViewType(position)) {
case TYPE_SENT:
ViewHolder0 viewHolder0 = (SentMsgVH)holder;
...
break;
case TYPE_RECEIVED:
ViewHolder2 viewHolder2 = (ReceivedMsgVh)holder;
...
break;
}
}
}
接口MsgType{
int TYPE_SENT=1;
int TYPE_RECEIVED=2;
}
类Msg实现MsgType
{
字符串文本;
int型;
公共消息(字符串文本,int类型){
//设置
}
公共字符串getText(){
返回文本;
}
公共int getType(){
返回类型;
}
}
公共类MyAdapter扩展了RecyclerView.Adapter{
列出MSG;
类SentMsgVH扩展了RecyclerView.ViewHolder{
...
公共SentMsgVH(查看项目视图){
...
}
}
类ReceivedMsgVh扩展了RecyclerView.ViewHolder{
...
公共接收DMSGVH(查看项目视图){
...
}
@凌驾
public int getItemViewType(int位置){
返回msgs.get(position.getType();
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
观点五;
开关(视图类型){
已发送的案例类型:
v=…;//膨胀视图
返回新的SentMsgVH(v);
收到的病例类型:
v=…;//膨胀视图
返回新接收的DMSGVH(v);
}
}
@凌驾
公共无效onBindViewHolder(最终RecyclerView.ViewHolder,最终整型位置){
开关(getItemViewType(位置)){
已发送的案例类型:
ViewHolder0 ViewHolder0=(SentMsgVH)支架;
...
打破
收到的病例类型:
ViewHolder2 ViewHolder2=(ReceivedMsgVh)holder;
...
打破
}
}
}
在各自的视图持有者中,您应该根据需要放大适当的布局。很可能您没有正确处理回收的视图。@Code peedient我已将布局添加到帖子中。如何处理它?mMessagesList.setAdapter(mAdapterCustom)
这一行是这里的问题,您设置了整个消息列表的适配器,因此它会转到整个列表的左侧。使用RecycleServiceWhi@jigarsavaliya我应该如何更改它?请告知包含if
语句的方法。除了在ChatActivity
中显示它的文本之外,您还应该显示实际的代码(public class ChatActivity扩展了…
以及包含它的方法)。但是要设置Left
或Right
,我必须在MessageAdapterCustom
中发送第三个参数。这就是为什么我将它放在部分if(currentUserID.equals(mCurrentUserID))中的原因
@bertojoris这正是问题所在。通过接受MessageAdapterCustompublic class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class ViewHolder0 extends RecyclerView.ViewHolder {
...
public ViewHolder0(View itemView){
...
}
}
class ViewHolder2 extends RecyclerView.ViewHolder {
...
public ViewHolder2(View itemView){
...
}
@Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
return position % 2 * 2;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 0: return new ViewHolder0(...);
case 2: return new ViewHolder2(...);
...
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolder0 viewHolder0 = (ViewHolder0)holder;
...
break;
case 2:
ViewHolder2 viewHolder2 = (ViewHolder2)holder;
...
break;
}
}
}
interface MsgType {
int TYPE_SENT = 1;
int TYPE_RECEIVED = 2;
}
class Msg implements MsgType
{
String text ;
int type;
public Msg(String text, int type) {
// set
}
public String getText() {
return text;
}
public int getType() {
return type;
}
}
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<Msg> msgs;
class SentMsgVH extends RecyclerView.ViewHolder {
...
public SentMsgVH(View itemView){
...
}
}
class ReceivedMsgVh extends RecyclerView.ViewHolder {
...
public ReceivedMsgVh(View itemView){
...
}
@Override
public int getItemViewType(int position) {
return msgs.get(position).getType();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType) {
case TYPE_SENT:
v = ... ; // inflate view
return new SentMsgVH(v);
case TYPE_RECEIVED:
v = ...; // inflate view
return new ReceivedMsgVh(v);
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
switch (getItemViewType(position)) {
case TYPE_SENT:
ViewHolder0 viewHolder0 = (SentMsgVH)holder;
...
break;
case TYPE_RECEIVED:
ViewHolder2 viewHolder2 = (ReceivedMsgVh)holder;
...
break;
}
}
}