Issue
I am making an app that has three tabs (similar to the WhatsApp Layout). The three tabs are Friends, Family and Contacts. Each tab has a List in it. Each List item also has the following view: Name on the left hand side, Description below the Name and a Button that has background as a Drawable on the right hand side, on the same line as the Name. (I've posted this before but have re-posted this now because I've been able to figure out the main error and reduce the code that I need to put here)
Each listview item contains a class (Friend, Family, Contact). All the three classes have a flag (canViewYouOnlineFlag). If this flag is set to true, the respective contact, family or friend will know that you are online and vice versa. If the flag is set to true, the color of the button must be blue and if the flag is set to false, the color of the button must be black.
The problem I face is that the button is not rendering correctly when the tab is opened. Typically, the button's color must be set based on the CanViewYouOnlineFlag of the Object contained in the Listview item. However, the current listview item's button's color is being changed by the next listview item's Object's CanViewYouOnlineFlag when the getView function is called on the next listview item. For example:
3 Items in the listview, each having an object and the CanViewYouOnlineflags for the three are the following: Listview item 1: true, Listview item 2: false, Listview item 3: false.
The color of the buttons of the list view items must be blue, black, black upon rendering. However, it turns out to be all black.
Similarly, if listview item 3's object's flag is set to "TRUE", then all the buttons are blue in color. Basically, the color of the buttons are being decided by the object present in the last Listview item. The actual flag of the object contained in the listview item is not the issue and I've verified this also (i.e. Object flag is true but button is still rendering black because the button of the last listview item is black). Please help me resolve this. The following is the xml file for the main_lp_view_item layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="@+id/main_lp_text"
android:textSize="18sp"
android:textColor="@color/colorPrimaryDark"
android:focusable="false" />
<TextView
android:id="@+id/main_lp_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/main_lp_text"
android:textSize="13sp"
android:focusable="false" />
<Button
android:id="@+id/can_view_you_online"
android:layout_width="33sp"
android:layout_height="29sp"
android:layout_above="@+id/main_lp_subtitle"
android:layout_marginTop="10dp"
android:textStyle="bold"
android:background="@drawable/lp_list_button"
android:layout_alignParentEnd="true"
android:focusable="false"
/>
</RelativeLayout>
The following is the code for the LPListAdapter class where the Listviews are initiated
public class LPListItemAdapter<T> extends BaseAdapter{ //Class for rendering each ListItem
Context context;
List<T> rowItems;
public LPListItemAdapter(Context context, List<T> rowItems)
{
this.context=context;
this.rowItems=rowItems;
}
@Override
public int getCount()
{
return rowItems.size();
}
@Override
public Object getItem(int position)
{
return rowItems.get(position);
}
@Override
public long getItemId(int position)
{
return rowItems.indexOf(getItem(position));
}
private class ViewHolder{
TextView main_text; //Display Name
TextView subtitle; //Display Description
Button can_view_you_online; //Button to set and display status of CanViewYouOnline flag of the class
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder=null;
LayoutInflater mInflater= (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
holder = new ViewHolder();
if(convertView==null)
{
convertView=mInflater.inflate(R.layout.main_lp_view_item, null);
holder.main_text= (TextView) convertView.findViewById(R.id.main_lp_text);
holder.subtitle= (TextView) convertView.findViewById(R.id.main_lp_subtitle);
holder.canViewYouOnline= (Button) convertView.findViewById(R.id.can_view_you_online);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
final T rowItem= rowItems.get(position);
String main_text;
String subtitle;
if(rowItem instanceof Friends) //If Row Item is a Friend class
{
main_text= ((Friends) rowItem).getName();
subtitle= ((Friends) rowItem).getDescription();
}
else if(rowItem instanceof Family) //If Row Item is a Family class
{
main_text= ((Family) rowItem).getName();
subtitle= ((Family) rowItem).getDescription();
}
else if(rowItem instanceof Contact) //If Row Item is a Contact class
{
main_text=((Contact) rowItem).getName();
subtitle=((Contact) rowItem).getDescription();
}
else
{
main_text="NA";
subtitle="";
}
holder.main_text.setText(main_text);
holder.subtitle.setText(subtitle);
if(getflagstatus(rowItem)) //If rowItem's canViewYouOnline flag is set true, then let color of button be default (i.e. blue)
holder.canViewYouOnline.getBackground().clearColorFilter();
else //Else (if it false), make it black
holder.canViewYouOnline.getBackground().setColorFilter(Color.argb(255, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);
//This part of the function is the problem because the color filter of the drawable of the button in the current list item gets overriden when
//this same code is executed for the next listview item.
holder.canViewYouOnline.setOnClickListener(new View.OnClickListener() {
boolean buttonClickFlag;
@Override
public void onClick(View v) { //The Onclick function allows one to click the button on the list item and set/reset the canViewYouOnline flag. It is working fine.
buttonClickFlag=getflagstatus(rowItem); //get buttonClickFlag from canViewYouOnline flag status
if(buttonClickFlag==false) //If buttonClickFlag is false
{
v.getBackground().clearColorFilter(); //set color of button drawable to default (which is blue)
buttonClickFlag=true; //set buttonClickflag to true
}
else //if buttonClickFlag is true
{
v.getBackground().setColorFilter(Color.argb(255,0,0,0), PorterDuff.Mode.SRC_ATOP); //set color of button drawable to black
buttonClickFlag=false; //set buttonClickflag to false
}
//update the canViewYouOnline flag in the rowItem by calling the onlineStatusUpdateButtonOnClickActivity function.
//Function is working perfectly so is not included in the stack overflow entry due to space constraints
onlineStatusUpdateButtonOnClickActivity(rowItem, buttonClickFlag,v);
}
});
return convertView;
}
public boolean getflagstatus(T rowItem)
{
//Function to get the CanViewYouOnlineFlag() from the underlying class in the rowItem
boolean flagStatus=false;
if(rowItem instanceof Friends)
flagStatus=((Friends) rowItem).getCanViewYouOnlineFlag();
else if(rowItem instanceof Family)
flagStatus=((Family) rowItem).getCanViewYouOnlineFlag();
else if(rowItem instanceof Contact)
flagStatus= ((Contact) rowItem).getCanViewYouOnlineFlag();
return flagStatus;
}
public void onlineStatusUpdateButtonOnClickActivity(T rowItem, boolean mLBflag, View convertView) {//WORKS FINE SO NOT PUTTING IT HERE DUE TO SPACE CONSTRAINT}
}
Solution
I got the answer. If you use a single drawable resource and merely change the color when the flag is changed, this error will come. Instead, use two drawables and when CanViewYouOnline is true, set background of button as drawable 1 and when CanViewYouOnline is false, set background of button as drawable 2.
Answered By - Thanatos
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.