Android custom adapter not working properly for chat listview

1.7k views Asked by At

Hello everyone I am new to android. I am working on chat application and now I have problem with custom adapter. Its working perfectly with text chat but when I have load image in listview its occurring problem. Problem is that when I scroll chat 2-3 time image override to text. I have check my all code with log and its show only one time image implementation for specific position but in listview its show images randomly. I have try much more google and related question but nothing help me.

Here when I load first time chat..its showenter image description here

and when I scroll sometimes its show image at every text chat.

enter image description here

Can anyone help me.plz.Thanks.

Here is my adapter:

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;
    }
}

here is my layouts http://pastebin.com/6xSqGpKC

1

There are 1 answers

1
Prakash Gajera On
acticity_chat_singlemessage.xml

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

    <LinearLayout
        android:id="@+id/singleMessageContainer"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/singleMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="80dp">
    </ListView>

    <RelativeLayout
        android:id="@+id/form"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:orientation="vertical" >

        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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_width="wrap_content"
            android:layout_height="wrap_content"
            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;
    }
}