listview dynamic message using Flags - android

i am working on a chat application. I am able to send and receive message normally. But when i try to integrate bubble message, i need guidance. i have 2 layouts
left layout(Display sent message by me, 2. right layout() display received messages. I am able to display message i am sending in bubble message. I am not able to display the received message. How should i go ahead.
sample code is given below:
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row = null;
String jid = null;
String even_color, odd_color;
SharedPreferences prefList = getSharedPreferences("PrefsFile",
MODE_PRIVATE);
even_color = prefList.getString("even_bubble_color", "pink");
odd_color = prefList.getString("odd_bubble_color", "green");
int even_color_id = getResources().getIdentifier(even_color,
"drawable", "com.teks.chilltwit"), odd_color_id = getResources()
.getIdentifier(odd_color, "drawable", "com.teks.chilltwit");
//ImageView even_view, odd_view;
// System.out.println("Timeline: Position: "+position+", Length: "+data.length);
// if(position!=data.length-1){
if (jid != null) {
row = inflater.inflate(R.layout.list_row_layout_odd, parent,
false);
TextView textLabel = (TextView) row.findViewById(R.id.text);
textLabel.setText(datav);
}
else {
row = inflater.inflate(R.layout.list_row_layout_even, parent,
false);
TextView textLabel = (TextView) row.findViewById(R.id.text);
textLabel.setText("" + messages);
}
return row;
}
}
In the above code, i need to display left layout if i send the message and else i need to display right layout if i receive message. Please guide me in this issue.
Thanks.

So, the problem here is that the jid is always not null?

Related

Change Image of image button in list view

I checked on Stackoverflow, some people asked about changing the image, but non of the solutions helped me.
I have an ImageButton in listItem of list view. I want to change the image of ImageButton on clicking the ImageButton. It is displaying the toast but not changing the image.
Any help would be appreciated. Thanks in advance.
Below is my code...
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.fragment_contacts_item_list, null);
contactName = (TextView)rowView.findViewById(R.id.name_contact);
contactNumber = (TextView)rowView.findViewById(R.id.number_contact);
contactPic = (ImageView)rowView.findViewById(R.id.quickContactBadge_contact);
contactStatusButton = (ImageButton)rowView.findViewById(R.id.configuration_button);
convertView = rowView;
contactArray = new ArrayList<ContactModel>();
int status = contactList.get(position).getButtonStatus();
if(status == 0)
contactStatusButton.setImageResource(R.drawable.grey);
else if(status == 1) //toggle button is on
contactStatusButton.setImageResource(R.drawable.green);
else
contactStatusButton.setImageResource(R.drawable.red);
contactStatusButton.setVisibility(View.VISIBLE);
contactStatusButton.setBackgroundColor(Color.TRANSPARENT);
contactStatusButton.setTag(position);
contactStatusButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
int position = (Integer) view.getTag();
model.setName(contactList.get(position).getName());
model.setNumber(contactList.get(position).getNumber());
model.setPhoto(contactList.get(position).getPhoto());
ContactAdapter.contactArray.add(contactList.get(position));
contactStatusButton.setImageResource(R.drawable.green);
Toast.makeText(context, "contact Number: " + contactList.get(position).getNumber(), Toast.LENGTH_SHORT).show();
}
});
model = new ContactModel(contactList.get(position).getName(), contactList.get(position).getNumber(), 0);
model.setName(contactList.get(position).getName());
model.setNumber(contactList.get(position).getNumber());
model.setButtonStatus(contactList.get(position).getButtonStatus());
Bitmap pic = Utilities.getPhoto(contactList.get(position).getPhoto());
model.setPhoto(contactList.get(position).getPhoto());
contactName.setText(contactList.get(position).getName());
contactNumber.setText(contactList.get(position).getNumber());
contactPic.setImageBitmap(pic);
return convertView;
}
Your views all seem to be defined as members of the enclosing class. That means they are constantly getting reassigned to different views whenever getView is called.
Instead, you should assign your views locally to the method, and make them final so that they can be referenced inside your click handler:
final View rowView = inflater.inflate(R.layout.fragment_contacts_item_list, null);
final TextView contactName = (TextView)rowView.findViewById(R.id.name_contact);
final TextView contactNumber = (TextView)rowView.findViewById(R.id.number_contact);
final ImageView contactPic = (ImageView)rowView.findViewById(R.id.quickContactBadge_contact);
final ImageButton contactStatusButton = (ImageButton)rowView.findViewById(R.id.configuration_button);
You're also making the same mistake with model in the click handler. You need to make sure you're using the model associated with the row, not whatever model happens to be left in the class member.
Also, you should note that you're not actually recycling the rows. You're creating a new row every time. This is defeating one of the main purposes of ListView, which is to not have to create new views for each row. You might want to find one of the many ListView tutorials out there to help you do this correctly.
I think it will mostly solve you problem to invalidate the view after you have updated its image resource. Give this a try for your onClick():
#Override
public void onClick(View view) {
int position = (Integer) view.getTag();
model.setName(contactList.get(position).getName());
model.setNumber(contactList.get(position).getNumber());
model.setPhoto(contactList.get(position).getPhoto());
ContactAdapter.contactArray.add(contactList.get(position));
contactStatusButton.setImageResource(R.drawable.green);
contactStatusButton.invalidate(); //The View now needs to be redrawn
Toast.makeText(context, "contact Number: " + contactList.get(position).getNumber(), Toast.LENGTH_SHORT).show();
}

ListView item style keeps changing randomly when there are multiple style in the same ListView

I have made a chat application where the chat view is formed from many rows in a ListView where messages sent by the user are displaying in white and messages received by friend are displayed in blue.
This behavior works fine, but when I scroll the list after becoming really big (e.g. 30 rows) the colors are messed. I use different layouts for each row, white row layout and blue row layout.
When I scroll multiple times up and down the list the colors keeps switching randomly (i.e. some of my messages are in blue and others in white, and some of the other end (the friend chatting with me) becomes white and other messages become blue in a random way.
I'll give you a snipped preview on the code used:
This is the getView method in my custom adapter which extends BaseAdapter:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final int pos = position;
String from = messages.get(pos).getFrom();
if (convertView == null) {
holder = new ViewHolder();
// If message is sent by me (the user)
if(from.toString().toLowerCase().equals("me")){
convertView = mInflater.inflate(R.layout.chat_msg_row2, null);
}
// if message is sent by his friend (the other end user)
else{
convertView = mInflater.inflate(R.layout.chat_msg_row, null);
}
holder.userName = (TextView) convertView.findViewById(R.id.msgusername);
holder.userImage = (ImageView) convertView.findViewById(R.id.ppic);
holder.date = (TextView) convertView.findViewById(R.id.msgdate);
holder.text = (TextView) convertView.findViewById(R.id.msg);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.userName.setText( messages.get(pos).getFrom() );
holder.text.setText( messages.get(pos).getText() );
holder.date.setText( messages.get(pos).getDate() );
String img = messages.get(pos).getImage();
if(img.substring(0,4).equalsIgnoreCase("http") ){
try{
ImageLoader imloader = new ImageLoader( ChatActivity.this );
holder.userImage.setTag(img);
imloader.DisplayImage( img, ChatActivity.this , holder.userImage );
}
catch(Exception e){
e.printStackTrace();
}
}
return convertView;
}
public long getItemId(int position){
return 1;
}
public class ViewHolder{
TextView userName;
ImageView userImage;
TextView text;
TextView date;
}
The two layouts, chat_msg_row2 and chat_msg_row, are identical except for the Drawable used, where one is using a white image and the other using a blue image.
I recently faced similar problem. What I did was remove the
if (convertView == null)
and the return the View itself. What that above code does is : it checks if there are previous cache present in the present list. If present it re-uses previously present list. Hope it helps
As you didn't use the getItemViewType and the getViewTypeCount methods of the adapter, then the ListView will assume you only have one type of row(although you actually use two types) and will recycle rows as they appear in the list. So, when the convertView is not null you get a recycled row that could be either one of those two types depending on its position.
But the methods above should be implemented only if your rows are really different(extra widgets, placement rules etc). If your two rows are different only by the background image then you need only one row and you'll be setting the background based on your app's logic, something like this:
//...
if (convertView == null) {
holder = new ViewHolder();
// just inflate one of the rows if they are identical
convertView = mInflater.inflate(R.layout.chat_msg_row, parent, false);
holder.userName = (TextView) convertView.findViewById(R.id.msgusername);
holder.userImage = (ImageView) convertView.findViewById(R.id.ppic);
holder.date = (TextView) convertView.findViewById(R.id.msgdate);
holder.text = (TextView) convertView.findViewById(R.id.msg);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// set the background image as desired
if(from.toString().toLowerCase().equals("me")){
// I assumed you set the background on the root of the View row, convertView
// otherwise search for the desired view in convertView and set the background
convertView.setBackgroundResource(R.drawable.the_me_background_drawable);
} else {
convertView.setBackgroundResource(R.drawable.the_other_user_background_drawable);
}
// ...

android chat ListView getView updating wierdly

i've built a chat application.
inside my chat messages Activity, i have a ListView which shows all text message.
inside each text messages i have a TextView which will by default write "Sending..." and i want it to be updated after the message is sent.
inside each ChatMessage object i have a sent and time property. if sent is true i will show in the TextView the time, and if it's false i will write "Sending" as written above.
when i'm sending a new message, i'm adding a new view to the ListView adapter, and from some reason it shows that message was sent although it didn't... can't really understand why.
this is my ArrayAdapter's getView() and holder class:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ChatMessage chatMessage = chatMessagesArrayList.get(position);
ChatMessageHolder chatMessageHolder = null;
if (row == null)
{
if (chatMessage.getSenderId() == app.getFacebookCurrentUser().getId())
row = LayoutInflater.from(context).inflate(layoutResourceId, null);
else
row = LayoutInflater.from(context).inflate(R.layout.chat_green, null);
chatMessageHolder = new ChatMessageHolder();
chatMessageHolder.message = (TextView) row.findViewById(R.activity_chat.message);
chatMessageHolder.sentTime = (TextView) row.findViewById(R.activity_chat.sent_time);
chatMessageHolder.isSent = chatMessage.isSent();
row.setTag(chatMessageHolder);
}
else
{
chatMessageHolder = (ChatMessageHolder) row.getTag();
}
chatMessageHolder.message.setText(chatMessage.getMessage());
if (chatMessageHolder.isSent)
chatMessageHolder.sentTime.setText(app.getDateTime(chatMessage.getTime()));
return row;
}
private static class ChatMessageHolder
{
TextView message, sentTime;
boolean isSent = false;
}
i can't really understand why doesn't it write the time or "Sending..." according to the isSent boolean flag...
It's because the ListView recycles previous views (that's what the convertView variable is). Likely it's recycling another view that was already set to "Sent", and you're never handling the alternate case where chatMessagerHolder.isSent is false. You should avoid setting chatMessageHolder.isSent = chatMessage.isSent(); until after that first if-else block. That first if-else should just be to initialize the view or recycle the object. Also, when you check if(chatMessageHolder.isSent) you should also handle what the TextView should say if that is false (i.e. in a followup else statement) since the views are recycled.

listview with dynamic data from xmpp

I am working on android chat application. I am facing a problem in send and receive function using xmpp. I am able to send message from emulator to xmpp and receive message from xmpp. But i am facing issue in displaying the incoming and outgoing message in a list view. I am confused how to give the condition to set view layout.
if(message from xmpp) {
TextView textLabel = (TextView) row.findViewById(R.id.textb); // if message received dislay in left side textview
textLabel.setText(receiveddata); //receiveddata contains arraylist of incoming message
} else (message from me) {
TextView textLabel = (TextView) row.findViewById(R.id.texts); // if message sent by me dislay in right side textview
textLabel.setText(sentdata); //sentdata contains arraylist of outgoing message
}
Kindly tell me how can i do this.
Thanks
You can create an adapter class having two layout having same field. use if condition for incoming and outgoing messages. and inflate accordingly.
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
entry = list.get(position);
if (convertView == null) {
if (getItemViewType(position) == 0) {
convertView = inflator.inflate(
R.layout.messages_even_list_layout, null);
} else {
convertView = inflator.inflate(
R.layout.messages_odd_list_layout, null);
}

android listview message among two different layouts

| have almost got my application working. Now i am in final stage. I am struck with an issue to display sent and received message in dynamic listview. Based on data sent or received i need to display the text in listview. I am able to view sent message in. I am able to receive the message from receiver but i am unable to display that in a listview.
sample code:
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row;
String query = null;
// String even_color, odd_color;
SharedPreferences prefList = getSharedPreferences("PrefsFile",
MODE_PRIVATE);
if(query == data){
row = inflater.inflate(R.layout.list_row_layout_odd, parent,
false);
TextView textLabel = (TextView) row.findViewById(R.id.text);
textLabel.setText(data);
}
else
{
row = inflater.inflate(R.layout.list_row_layout_even, parent,
false);
TextView textLabel = (TextView) row.findViewById(R.id.text);
textLabel.setText(datas);
}
return row;
}
}
If i sent message i need to display the msg in ie(list_row_layout_odd) and if i recieve message i need to display in (list_row_layout_even) layout.
please help me in solving this issue.
Thanks in advance.

Categories

Resources