Android 自定义适配器无法正常用于聊天列表视图

Posted

技术标签:

【中文标题】Android 自定义适配器无法正常用于聊天列表视图【英文标题】:Android custom adapter not working properly for chat listview 【发布时间】:2015-09-09 01:55:30 【问题描述】:

大家好,我是安卓新手。我正在开发聊天应用程序,现在我遇到了自定义适配器的问题。它与文本聊天完美配合,但是当我在列表视图中加载图像时,它会出现问题。问题是,当我滚动聊天 2-3 次时,图像覆盖为文本。我已经用日志检查了我的所有代码,它只显示特定位置的一次图像实现,但在列表视图中它随机显示图像。我尝试了更多谷歌和相关问题,但没有任何帮助。

当我加载第一次聊天时在这里..它的 show

当我滚动时,有时它会在每次文字聊天时显示图像。

谁能帮帮我。plz。谢谢。

这是我的适配器:

public class ChatMainAdapter extends BaseAdapter 

    private static final int TYPE_ITEM_ME = 0;
    private static final int TYPE_ITEM_OTHER = 1;
    private Context context;
    private ArrayList < ChatMessageLocalDBModel > arrayList;
    private static String currentUserObjectId;
    private Bitmap myBimap, UserBitmap;

    public ChatMainAdapter(Context context, ArrayList < ChatMessageLocalDBModel > arrayList, String currentUserObjectId, Bitmap userBitmap, Bitmap myBimap) 
        this.context = context;
        this.arrayList = arrayList;
        this.currentUserObjectId = currentUserObjectId;
        this.UserBitmap = userBitmap;
        this.myBimap = myBimap;
    

    @Override
    public int getCount() 
        return arrayList.size();
    

    @Override
    public Object getItem(int position) 
        return position;
    

    @Override
    public long getItemId(int position) 
        return position;
    

    @Override
    public int getItemViewType(int position) 
        String isMe = arrayList.get(position).getFrom();
        return isMe.equalsIgnoreCase(currentUserObjectId) ? TYPE_ITEM_ME : TYPE_ITEM_OTHER;
    

    @Override
    public int getViewTypeCount() 
        return 2;
    

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) 

        ViewHolder holder = null;
        final int type;
        type = getItemViewType(position);
        if (convertView == null) 
            holder = new ViewHolder();
            switch (type) 
                case TYPE_ITEM_ME:
                    
                        convertView = LayoutInflater.from(context).inflate(
                        R.layout.chat_listview_item_me, null);
                        holder.imgViewUserPic = (ImageView) convertView.findViewById(R.id.chat_item_ivProfileMe);
                        holder.body = (TextView) convertView.findViewById(R.id.chat_item_tv_me_message);
                        holder.time = (TextView) convertView.findViewById(R.id.chat_item_tv_me_time);
                        holder.llyPic = (LinearLayout) convertView.findViewById(R.id.chat_lly_image);
                        holder.llyPic.setBackgroundResource(0);
                        holder.body.setTextIsSelectable(true);
                    
                    break;
                case TYPE_ITEM_OTHER:
                    
                        convertView = LayoutInflater.from(context).inflate(
                        R.layout.chat_listview_item_other, null);
                        holder.imgViewUserPic = (ImageView) convertView.findViewById(R.id.chat_item_ivProfileOther);
                        holder.body = (TextView) convertView.findViewById(R.id.chat_item_tv_other_message);
                        holder.time = (TextView) convertView.findViewById(R.id.chat_item_tv_other_time);
                        holder.body.setTextIsSelectable(true);
                    
                    break;
            
            convertView.setTag(holder);
         else 
            holder = (ViewHolder) convertView.getTag();
        
        Log.i("NPath", "" + "Pos:" + position + " :- " + arrayList.get(position).getPath());
        if (arrayList.get(position).getPath().equalsIgnoreCase("NO IMAGE")) 
            holder.body.setText(arrayList.get(position).getMessage());
            holder.time.setText(arrayList.get(position).getTime());
            Log.i("NPath", "pos:" + position + "" + "is text and is : " + arrayList.get(position).getMessage() + "" + type);
         else 
            Log.i("NPath", "pos:" + position + "" + "is image:" + type);
            holder.body.setVisibility(View.GONE);
            holder.time.setVisibility(View.GONE);
            File path = new File("" + arrayList.get(position).getPath());
            if (path.exists()) 
                Bitmap mBitmap = BitmapFactory.decodeFile(arrayList.get(position).getPath());
                final BitmapDrawable background = new BitmapDrawable(mBitmap);
                holder.llyPic.setVisibility(View.VISIBLE);
                holder.llyPic.setBackgroundDrawable(background);
             else 
                convertView.setVisibility(View.GONE);
                Log.e("NFILENOEXICST", "No file exist");
            
        

        if (type == TYPE_ITEM_ME) 
            holder.imgViewUserPic.setImageBitmap(myBimap);
         else 
            holder.imgViewUserPic.setImageBitmap(UserBitmap);
        

        final ViewHolder finalHolder = holder;
        holder.body.setOnLongClickListener(new View.OnLongClickListener() @Override
            public boolean onLongClick(View v) 
                ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
                cm.setText(finalHolder.body.getText());
                Toast.makeText(context, "Copied to clipboard", Toast.LENGTH_SHORT).show();
                return false;
            
        );

        return convertView;
    

    final static class ViewHolder 
        public ImageView imgViewUserPic;
        public TextView body;
        public TextView time;
        public LinearLayout llyPic;
    

这是我的布局http://pastebin.com/6xSqGpKC

【问题讨论】:

无用的问题..邮政编码 您的适配器出现问题,请同时发布代码 @WillTorres 我已经更新了我的代码 @WillTorres 你想要哪种布局..???我的意思是主布局或 itemview 布局..?? 提供的代码中使用的所有相关布局?你不知道如何正确提问吗? 【参考方案1】:
acticity_chat_singlemessage.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_ >

    <LinearLayout
        android:id="@+id/singleMessageContainer"
        android:layout_
        android:layout_ >

        <TextView
            android:id="@+id/singleMessage"
            android:layout_
            android:layout_
            android:layout_gravity="center"
            android:layout_margin="5dip"
            android:background="@drawable/bubble_b"
            android:paddingLeft="10dip"
            android:text="Hello bubbles!"
            android:textColor="@android:color/primary_text_light" />
    </LinearLayout>

</LinearLayout>

---------------------------------------------------------------------
activity_chat.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_
        android:layout_
        android:layout_marginBottom="80dp">
    </ListView>

    <RelativeLayout
        android:id="@+id/form"
        android:layout_
        android:layout_
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:orientation="vertical" >

        <EditText
            android:layout_
            android:layout_
            android:inputType="textMultiLine"
            android:ems="10"
            android:id="@+id/chatText"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_toLeftOf="@+id/buttonSend" />

        <Button
            android:layout_
            android:layout_
            android:text="Send"
            android:id="@+id/buttonSend"
            android:layout_alignBottom="@+id/chatText"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true" />
    </RelativeLayout>

</RelativeLayout>

----------------------------------------------------------------
ChatArrayAdapter.java activity class

public class ChatArrayAdapter extends ArrayAdapter<ChatMessage> 

    private TextView chatText;
    private List<ChatMessage> chatMessageList = new ArrayList<ChatMessage>();
    private LinearLayout singleMessageContainer;

    @Override
    public void add(ChatMessage object) 
        chatMessageList.add(object);
        super.add(object);
    

    public ChatArrayAdapter(Context context, int textViewResourceId) 
        super(context, textViewResourceId);
    

    public int getCount() 
        return this.chatMessageList.size();
    

    public ChatMessage getItem(int index) 
        return this.chatMessageList.get(index);
    

    public View getView(int position, View convertView, ViewGroup parent) 
        View row = convertView;
        if (row == null) 
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.activity_chat_singlemessage, parent, false);
        
        singleMessageContainer = (LinearLayout) row.findViewById(R.id.singleMessageContainer);
        ChatMessage chatMessageObj = getItem(position);
        chatText = (TextView) row.findViewById(R.id.singleMessage);
        chatText.setText(chatMessageObj.message);
        chatText.setBackgroundResource(chatMessageObj.left ? R.drawable.bubble_a : R.drawable.bubble_b);
        singleMessageContainer.setGravity(chatMessageObj.left ? Gravity.LEFT : Gravity.RIGHT);
        return row;
    

    public Bitmap decodeToBitmap(byte[] decodedByte) 
        return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
    



---------------------------------------------------------------
ChatBubbleActivity.java  activity class 

public class ChatBubbleActivity extends Activity 
    private static final String TAG = "ChatActivity";

    private ChatArrayAdapter chatArrayAdapter;
    private ListView listView;
    private EditText chatText;
    private Button buttonSend;

    Intent intent;
    private boolean side = false;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        Intent i = getIntent();
        setContentView(R.layout.activity_chat);

        buttonSend = (Button) findViewById(R.id.buttonSend);

        listView = (ListView) findViewById(R.id.listView1);

        chatArrayAdapter = new ChatArrayAdapter(getApplicationContext(), R.layout.activity_chat_singlemessage);
        listView.setAdapter(chatArrayAdapter);

        chatText = (EditText) findViewById(R.id.chatText);
        chatText.setOnKeyListener(new OnKeyListener() 
            public boolean onKey(View v, int keyCode, KeyEvent event) 
                if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) 
                    return sendChatMessage();
                
                return false;
            
        );
        buttonSend.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View arg0) 
                sendChatMessage();
            
        );

        listView.setTranscriptMode(AbsListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        listView.setAdapter(chatArrayAdapter);

        //to scroll the list view to bottom on data change
        chatArrayAdapter.registerDataSetObserver(new DataSetObserver() 
            @Override
            public void onChanged() 
                super.onChanged();
                listView.setSelection(chatArrayAdapter.getCount() - 1);
            
        );
    

    private boolean sendChatMessage()
        chatArrayAdapter.add(new ChatMessage(side, chatText.getText().toString()));
        chatText.setText("");
        side = !side;
        return true;
    



-------------------------------------------------------------
ChatMessage.java class file

public class ChatMessage 
    public boolean left;
    public String message;

    public ChatMessage(boolean left, String message) 
        super();
        this.left = left;
        this.message = message;
    

【讨论】:

谢谢@prakash。但我已经这样做了。它工作正常。但我必须在我的应用程序中加载两个视图。

以上是关于Android 自定义适配器无法正常用于聊天列表视图的主要内容,如果未能解决你的问题,请参考以下文章

Android:自定义列表视图无法正常工作

在android中使用自定义列表视图时无法设置左右对话

Android - 将搜索栏添加到自定义列表视图和简单适配器

使用自定义适配器自定义 Android ListView

Android - 通过 getView 函数在自定义 listView 适配器内设置 ImageView 的源无法正常工作

带有复选框和自定义适配器的 ListView,片段无法正常工作