Textview background repeats in a listview - android

So the problem that i am facing, is that when i try to set dynamically the background of a textView that belongs to a listView, the background that i set, is set for other textViews too..it repeats itself...i saw that these problems with listView items are common, but couldn't find a solution for me
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.product_item, null);
holder = new ViewHolder();
holder.increment = (Button) convertView.findViewById(R.id.increment);
holder.decrement = (Button) convertView.findViewById(R.id.decrement);
holder.pic_view_quantity = (TextView) convertView.findViewById(R.id.pic_view_quantity);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.pic_view_quantity.setText(products.get(position).getQuantity());
if (products.get(position).getQuantity().matches("[0-9]+")){
holder.pic_view_quantity.setBackgroundResource(R.drawable.transparent_rectangle); //this is where i set the background, to items that have a quantity
}
return convertView;
}
My layout:
<RelativeLayout
android:id="#+id/relativelayout"
android:layout_width="70dp"
android:layout_height="70dp" >
<ImageView android:id="#+id/pic_view"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginTop="5sp"
android:contentDescription="#string/product_picture" >
</ImageView>
<TextView
android:id="#+id/pic_view_quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/pic_view"
android:layout_alignTop="#+id/pic_view"
android:layout_alignRight="#+id/pic_view"
android:layout_alignBottom="#+id/pic_view"
android:layout_margin="1dp"
android:textSize="36sp"
android:gravity="center"
android:textColor="#FF0000" />
</RelativeLayout>

Add an else to the following statement
if (products.get(position).getQuantity().matches("[0-9]+")){
holder.pic_view_quantity.setBackgroundResource(R.drawable.transparent_rectangle); //this is where i set the background, to items that have a quantity
}
else {
holder.pic_view_quantity.setBackgroundResource(0);
}

Related

Alternate text and background color in listview

I am new to android, I am trying to display alternate text color and alternate background color, but only background color is working. When I try both, I'm getting error.
Here's the error shown in LogCat:
android.widget.RelativeLayout cannot be cast to android.widget.TextView
This is getView() method in my adapter class:
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder view;
if(convertView==null)
{
inflater = (LayoutInflater)mcontext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
view = new ViewHolder();
convertView = inflater.inflate(R.layout.awards_layout_circle, null);
view.txtViewTitle = (TextView) convertView.findViewById(R.id.Text_View);
view.imgViewFlag = (ImageView) convertView.findViewById(R.id.profile_image);
convertView.setTag(view);
}
else
{
view = (ViewHolder) convertView.getTag();
}
if (position % 2 == 0){
convertView.setBackgroundResource(R.color.colorNav);
((TextView) convertView).setTextColor(Color.WHITE);
} else {
convertView.setBackgroundResource(R.color.colorWhite);
((TextView) convertView).setTextColor(Color.BLACK);
}
view.txtViewTitle.setText(listAward.get(position));
view.imgViewFlag.setImageResource(listFlag.get(position));
return convertView;
}
And awards_layout_circle.xml using to item list:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/profile_image"
android:layout_width="match_parent"
android:layout_height="250dp"
android:src="#drawable/bunnyarj"
android:layout_gravity="center"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>
<TextView
android:id="#+id/Text_View"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18dp"
android:text="wsdwedwebd dwedbewd w"
android:fontFamily="sans-serif-medium"
android:layout_below="#+id/profile_image"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
you are using the ViewHolder. No reason to cast the convertView to any type of object (expecially to the wrong one). Just use
view.txtViewTitle.setTextColor()
in your if/else
You have change the code like this,
if (position % 2 == 0){
convertView.setBackgroundResource(R.color.colorNav);
((TextView) view.txtViewTitle).setTextColor(Color.WHITE);
} else {
convertView.setBackgroundResource(R.color.colorWhite);
((TextView) view.txtViewTitle).setTextColor(Color.BLACK);
}

Optimizing ListView adapter to display dynamic content in individual ListView items

I'm trying to display a ListView where individual list items feature a dynamic number of elements. Each item list will have a TextView for a date. Following the date, there can be between 2-5 elements featured.
ListItemA
DateTextView
2-5 TextView
ListItemB
DateTextView
2-5 TextView
ListItemC
DateTextView
2-5 TextView
...
With this current method, it displays the blank TextViews at the bottom of the ListView's item. Would there be a better way to do this?
I thought that convertView would have had methods to add layout elements to it, but that's not the case.
Adapter's getView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = this.inflater.inflate(R.layout.layout_list_item, parent, false);
holder.text_date_cashout = (TextView) convertView.findViewById(R.id.text_date_cashout);
holder.dynamic_views.add((TextView) convertView.findViewById(R.id.text_cashout1));
holder.dynamic_views.add((TextView) convertView.findViewById(R.id.text_cashout2));
holder.dynamic_views.add((TextView) convertView.findViewById(R.id.text_cashout3));
holder.dynamic_views.add((TextView) convertView.findViewById(R.id.text_cashout4));
holder.dynamic_views.add((TextView) convertView.findViewById(R.id.text_cashout5));
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
}
//get and set date from current cashOutHistory
CashOutHistory coh = cashOutHistory.get(position);
holder.text_date_cashout.setText(coh.getDate());
//loop individual cashOuts to display their values
int i = 0;
for (CashOut co : coh.getCashOutHistory() ){
holder.dynamic_views.get(i).setText(co.toString());
i++;
}
return convertView;
}
private class ViewHolder{
TextView text_date_cashout;
ArrayList<TextView> dynamic_views = new ArrayList<TextView>(5);
}
List item layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:text=""
android:id="#+id/text_date_cashout" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="#+id/text_cashout1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="#+id/text_cashout2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="#+id/text_cashout3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="#+id/text_cashout4" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:id="#+id/text_cashout5" />
</LinearLayout>
Edit #1
Loop showing and hidding the TextViews in my list item:
//loop individual cashOuts to display their values
int i = 0;
for (CashOut co : coh.getCashOutHistory() ){
holder.dynamic_views.get(i).setText(co.toString());
i++;
}
while(i < 5){
holder.dynamic_views.get(i).setVisibility(View.GONE);
i++;
}
You can hide each view you don't need showing for that particular item by using:
Boolean someCondition = true;
if (someCondition)
holder.dynamic_views.get(i).setVisibility(View.GONE);
Hope this helps.

too slow scrolling GridView android when I use resource background on layout

Let me explain my problem.
The GridView scrolling is too slow when I use resource background on Relative root layout.
my background file size is 114KB.
I used android:cacheColorHint="#00000000" or android:overScrollMode="never" with no success.
this is my xml code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/bg"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:layout_width="match_parent"
android:layout_height="125dp"
android:id="#+id/useful_applications"
android:layout_marginTop="35dp"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:choiceMode="singleChoice"
android:cacheColorHint="#00000000"
android:overScrollMode="never"
android:clickable="true"
android:numColumns="4"
android:gravity="center"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp" />
</RelativeLayout>
I use ArrayAdapter with holder pattern.
anyone can help me?
Update 1:
this is my adapter getView that I used holder pattern
#Override
public View getView(int position, View convertView, ViewGroup parent) {
UsefulApplicationHolder holder;
if (convertView == null) {
convertView =LayoutInflater.from(mContext).inflate(R.layout.component_application_icon, parent, false);
holder = new UsefulApplicationHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.score = (TextView) convertView.findViewById(R.id.score);
convertView.setTag(holder);
} else {
holder = (UsefulApplicationHolder) convertView.getTag();
}
Apps info = getItem(position);
holder.icon.setImageDrawable(info.getIcon());
String score = info.getScore();
if (Integer.valueOf(score) > 0) {
holder.score.setTextColor(mContext.getResources().getColor(R.color.green));
score = "+" + score;
} else if (Integer.valueOf(score) < 0) {
holder.score.setTextColor(mContext.getResources().getColor(R.color.red));
} else {
holder.score.setTextColor(mContext.getResources().getColor(R.color.light_gray));
}
holder.score.setText(score);
return convertView;
}

Android: ListView bug

I have a custom list view which has a Textview and an image. When I click on the textview a hidden layout will be expanded for that particular row. But what happening was, for eg., when I click on 2nd row, 10th row is also getting expanded. Here is my code,
CustomListAdapter.java
public View getView(final int position, View convertView, ViewGroup parent) {
holder = null;
DataFields rowItems = (DataFields) getItem(position);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.home_field_row, null);
holder = new ViewHolder();
holder.dataFields = items.get(position);
holder.mName = (TextView) convertView
.findViewById(R.id.hmFieldName);
holder.mDeleteImage = (ImageView) convertView
.findViewById(R.id.hmFieldDeleteImage);
holder.deleteMainRL = (RelativeLayout) convertView
.findViewById(R.id.hmdeleteMainRL);
holder.mDeleteImage.setTag(position);
holder.mName.setTag(position);
holder.deleteMainRL.setTag(position);
final View clickView = convertView;
holder.mName.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout displayAddInfo = (RelativeLayout)clickView.findViewById(R.id.displayRecordRL);
Animation expandAnim = expand(displayAddInfo,
true);
displayAddInfo
.startAnimation(expandAnim);
}
});
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.mName.setText(rowItems.getName());
return convertView;
}
How can I fix this? Any kind of help or suggestion is much appreciated. Thanks.
Update
list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/hmFieldMainRL"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/grid_shape" >
<TextView
android:id="#+id/hmFieldName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/displayRecordRL"
android:layout_alignParentLeft="true"
android:gravity="left"
android:padding="15dp"
android:shadowColor="#000000"
android:shadowDx="0"
android:shadowDy="0"
android:clickable="false"
android:shadowRadius="2"
android:text="#string/no_data"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#F2F2F2" />
<RelativeLayout
android:id="#+id/displayRecordRL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/hmFieldName"
android:layout_centerVertical="true"
android:layout_marginBottom="5dp"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:layout_marginTop="1dp"
android:background="#drawable/display_record_bg"
android:visibility="gone" >
<EditText
android:id="#+id/displayRecordName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_toLeftOf="#+id/displayRecordUpdate"
android:padding="10dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/displayRecordPwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#id/displayRecordName"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_toLeftOf="#+id/displayRecordShow"
android:inputType="textPassword"
android:paddingLeft="10dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/displayRecordAddInfoImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_below="#id/displayRecordPwd"
android:contentDescription="#string/right_arrow"
android:visibility="gone"
android:src="#drawable/info" />
<EditText
android:id="#+id/displayRecordAddInfo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/displayRecordAddInfoImg"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="2dp"
android:hint="Additional Information"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<ImageView
android:id="#+id/displayRecordUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#drawable/display_record_img"
android:contentDescription="#string/right_arrow"
android:padding="10dp"
android:src="#drawable/update_rec" />
<ImageView
android:id="#+id/displayRecordShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/displayRecordUpdate"
android:layout_marginTop="10dp"
android:contentDescription="#string/right_arrow"
android:padding="10dp"
android:src="#drawable/eye" />
<ImageView
android:id="#+id/displayRecordShowRed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/displayRecordUpdate"
android:layout_marginTop="10dp"
android:contentDescription="#string/right_arrow"
android:padding="10dp"
android:src="#drawable/redeye"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>
But what happening was, for eg., when I click on 2nd row, 10th row is also getting expanded.
You are fighting the way ListViews recycle the row layouts. But this is easy enough to deal with, first let's add a couple new class variables:
SparseBooleanArray expanded = new SparseBooleanArray();
LayoutInflater inflater; // initialize this in your constructor
Now we'll use expanded to check whether displayRecordRL should be visible:
public View getView(final int position, View convertView, ViewGroup parent) {
DataFields rowItems = (DataFields) getItem(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.home_field_row, null);
holder = new ViewHolder();
holder.dataFields = items.get(position);
holder.mName = (TextView) convertView
.findViewById(R.id.hmFieldName);
holder.mDeleteImage = (ImageView) convertView
.findViewById(R.id.hmFieldDeleteImage);
holder.deleteMainRL = (RelativeLayout) convertView
.findViewById(R.id.hmdeleteMainRL);
// Add this to your holder
holder.mAddInfo = (RelativeLayout) convertView
.findViewById(R.id.displayRecordRL);
holder.mDeleteImage.setTag(position);
holder.mName.setTag(position);
holder.deleteMainRL.setTag(position);
holder.mName.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Get the ViewHolder
holder = (ViewHolder) ((View) v.getParent()).getTag();
Animation expandAnim = expand(holder.mAddInfo, true);
holder.mAddInfo.startAnimation(expandAnim);
// Remember that this View is expanded
int pos = (Integer) v.getTag();
expanded.put(pos, true);
}
});
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.mName.setText(rowItems.getName());
if(expanded.get(position, false))
holder2.mAddInfo.setVisibility(View.VISIBLE);
else
holder2.mAddInfo.setVisibility(View.GONE);
return convertView;
}
Notice how this tracks whether each row should be visible and uses a simple if statement to make sure the recycled layout correctly shows or hide the "Add Info" section.
You need to add a attribute to your adapter, a simple int. When you click on an item, update the current selected position. When you build the view, check if position equals the selected position.
public View getView(final int position, View convertView, ViewGroup parent) {
if(this.selectedPosition == position){
//add a holder
else{
//don't add a holder
return convertview;
}
What I'm saying is that you are encountering a View recycling problem. If you modify item n°2 and then the view of item n°10 is build from the View n°2, you end up with an item unwanted (that will look as it was clicked).
When an item of your list is clicked:
1) update the selected item (attribute of your adapter). Example, if you click on item 12 of your listview, selectedItem = 12;
2) call method notifyDataSetChanged(). This will refresh the view of the list.
3) When you build the view (getView() of adapter), check for each position if it corresponds to the selected item. If it does, build your special view (I don't know exactly what you want to do). If it doesn't correspond to the selected item, build your view "normally"
Try to put the R.id.displayRecordRL as part of the viewholder and on the OnClick method call it.
holder.displayAddInfo = (RelativeLayout)clickView.findViewById(R.id.displayRecordRL);
and on the OnclickMethod :
Animation expandAnim = expand(holder.displayAddInfo,
true);
holder.displayAddInfo
.startAnimation(expandAnim);
}
The problem you experience could be that you animate a View (converView) that is being re-used for another item in your list-view when scrolling.
Look at this YouTube video and you may get an idea on how to solve your problem.
Chet Haase (Google engineer) "DevBytes" series "ListView Animations" :
https://www.youtube.com/watch?v=8MIfSxgsHIs#!

Android, changing background of list in array adapter?

In my application i have list which i inflate it with array adapter. every thing is OK and i have my result in the list.
I like to change background color of list (even rows red for example and odd rows green).
This is xml of my rows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout
android:id="#+id/rllist"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:layout_marginBottom="15dip"
>
<TextView
android:id="#+id/outstanding_contractdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:textSize="15sp" />
<TextView
android:id="#+id/outstanding_contractno"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/outstanding_contractdate"
android:paddingLeft="20dip"
android:textColor="#ffffff"
android:textSize="15sp" />
<TextView
android:id="#+id/outstanding_contractamount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textSize="15sp" />
</RelativeLayout>
</LinearLayout>
I have written following codes:
static class ViewHolder {
RelativeLayout rlList;
TextView tvContDate;
TextView tvContNo;
TextView tvContAmount;
}
and in Array Adapter I have this one:
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder;
View row = convertView;
if(row == null){
LayoutInflater inflater = getLayoutInflater();
row = inflater.inflate(R.layout.list_outstanding, parent, false);
//convertView = mInflater.inflate(R.layout.list_outstanding, parent, false);
holder = new ViewHolder();
holder.rlList = (RelativeLayout) convertView.findViewById(R.id.rllist);
holder.tvContDate = (TextView) row.findViewById(R.id.outstanding_contractdate);
holder.tvContNo = (TextView) row.findViewById(R.id.outstanding_contractno);
holder.tvContAmount = (TextView) row.findViewById(R.id.outstanding_contractamount);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
holder.tvContDate.setText(llData.get(position).split(",")[0].trim());
holder.tvContNo.setText(llData.get(position).split(",")[1].trim());
holder.tvContAmount.setText(llData.get(position).split(",")[2].trim());
if(position%2 != 0)
holder.rlList.setBackgroundColor(0x00FF00);
else
holder.rlList.setBackgroundColor(0XFF0000);
return(row);
}
after running application when i reach to this code, an error occurs. according to LogCat it is "Null Pointer Exception" and points to this line in getView():
holder.rlList = (RelativeLayout) convertView.findViewById(R.id.rllist);
it seems everything is OK, but I don't know where my problem is?!!!
===========
Update
I have changed above line to:
holder.rlList = (RelativeLayout) row.findViewById(R.id.rllist);
and now i have my result but background did not applied?!!!
Try using
if(position%2 != 0)
holder.rlList.setBackgroundColor(Color.parseColor("#00ff00"));
else
holder.rlList.setBackgroundColor(Color.parseColor("#ff0000"));

Categories

Resources