ListView adapter screws up item heights - java

I have a custom BaseAdapter used for a ListView. The usual layout of a row looks like on the first picture.
Gallery is here
But the list can also have items whose second line's string is empty, like on the second picture, and if that second line's string has a length equal to 0, the second line's view's setVisibility(View.GONE) method is called.
And when the list is filled with items so it's neccessary to scroll to see the most-bottom items, and you scroll down and there is an item with only one line, and you scroll back to top, some of the two-line items can lose their second line, like on the third picture.
A simillar thing happens when an item is deleted from the list - the item going on its place gets the height of the deleted one - like on the fourth picture (forget the colored bar).
So it seems that the adapter thinks the "Cookies" item is the same as the "Something" item... or something.
Why does it happen? How can i fix that?
Another gallery to show exactly what happens
Adapter code:
public class CounterItemAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<CounterItem> data;
private SQLiteOpenHelper helper;
private static LayoutInflater inflater = null;
public CounterItemAdapter(Activity activity, ArrayList<CounterItem> data, SQLiteOpenHelper helper) {
this.activity = activity;
this.data = data;
this.helper = helper;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return data.size();
}
#Override
public CounterItem getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return getItem(position).getId();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if(convertView == null)
view = inflater.inflate(R.layout.counter_list_item, null);
TextView nameView = (TextView)view.findViewById(R.id.nameView);
TextView descView = (TextView)view.findViewById(R.id.descView);
final TextView countView = (TextView)view.findViewById(R.id.countView);
ImageButton plusButton = (ImageButton)view.findViewById(R.id.plusButton);
final CounterItem counterItem;
counterItem = data.get(position);
nameView.setText(counterItem.getName());
if(counterItem.getDesc().length() == 0){
descView.setVisibility(View.GONE);
Log.d(HomeActivity.DEBUG_TAG, "GONE " + counterItem.getName() + ", LENGTH " + counterItem.getDesc().length());
}else
descView.setText(counterItem.getDesc());
countView.setText(counterItem.getCount() + "");
plusButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counterItem.increment(helper.getWritableDatabase());
countView.setText(counterItem.getCount() + "");
}
});
View categoryView = view.findViewById(R.id.category);
String colors[] = {"#ff99cc00",
"#ff00ddff",
"#ffffbb33",
"#ffaa66cc",
"#ffcc0000"};
Random rand = new Random();
String color = colors[rand.nextInt(colors.length)];
categoryView.setBackgroundColor(Color.parseColor(color));
return view;
}
}
Row layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false"
android:descendantFocusability="blocksDescendants"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/linearLayout" android:layout_centerVertical="true"
android:gravity="center_vertical" android:paddingLeft="12dp" android:paddingRight="12dp"
android:paddingBottom="8dp" android:paddingTop="8dp" android:id="#+id/linearLayout1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Counter name"
android:id="#+id/nameView"
android:textSize="16dp"/>
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="#+id/descView"
android:textSize="16dp"
android:textColor="#color/dividerGrey"
android:text="wtf"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:id="#+id/linearLayout" android:gravity="center_vertical" android:layout_centerVertical="true"
android:paddingTop="8dp" android:paddingBottom="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="13"
android:id="#+id/countView"
android:textSize="30dp"
android:layout_marginRight="13dp" android:textColor="#color/dividerGrey"/>
<View android:layout_width="0.5dp" android:layout_height="48dp"
android:background="#color/dividerGrey" android:id="#+id/plusDivider"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/plusButton"
android:src="#drawable/ic_button_increment"
style="#android:style/Widget.Holo.Light.ActionButton"
android:contentDescription="#string/plus_button"/>
</LinearLayout>
</RelativeLayout>

Well i suppose you use the ViewHolder pattern in a ListView right?
I don't want to try and explain the whole usage of this pattern as there are many other good tutorials.
So the case you describe happens, because the listAdapter reuses the convertView that was inflated for every object so if the last object for your listview has setVisibility(View.Gone) for your second line then when you scroll up all the other childs that become visible will also have visibility(View.Gone).
A simple workaround for this is to setVisibility for each row
like this:
if (convertView == null) {
convertView = (View) inflater.inflate(R.layout.view_item, null);
viewHolder = new ViewHolder();
viewHolder.itemName = (TextView) convertView.findViewById(R.id.item_name);
viewHolder.secondLine = (TextView) convertView.findViewById(R.id.second_line)
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
if(<-- your condition here-->){
secondLine.setVisibility(View.VISIBLE);
}
else{
secondLine.setVisibility(View.GONE);
}
And now that you have added the code for your adapter i believe that your mistake is here:
if(counterItem.getDesc().length() == 0){
descView.setVisibility(View.GONE);
Log.d(HomeActivity.DEBUG_TAG, "GONE " + counterItem.getName() + ", LENGTH " + counterItem.getDesc().length());
}else {
**descView.setVisibility(View.VISIBLE);**
descView.setText(counterItem.getDesc());
}
You should add code to set it visible again if needed bacause with your code when it gets gone for one of the rows it stays gone forever.
Update
Also for your second problem, whenever you delete an item from your listview you should remove the item from the adapter and call notifyDataSetChanged(); in order for the adapter to recreate the Views.

Related

ListView doesn't display on screen

I recently started to use ListView on Android Application and I'm not making it to display at the screen.
I saw many tutorials on how to do a custom Adapter and followed it line by line, but at the end I wasn't able to make the ListView display on my screen, I even let a fixed Text in one TextView to display at the ListView but it still didn't displayed it.
This is the constructor of my entity code:
public Classificacao(int colocacao, int time, int pontos) {
this.colocacao = colocacao;
this.time = time;
this.pontos = pontos;
}
This my Custom Adapter that extends "ArrayAdapter"
private Context context;
private ArrayList<Classificacao> classificacaoList;
ClassificacaoAdapter(Context context, ArrayList<Classificacao> classificacaoList) {
super(context, R.layout.layout_classificacao, classificacaoList);
this.context = context;
this.classificacaoList = classificacaoList;
}
#SuppressLint("SetTextI18n")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(convertView == null){
convertView = layoutInflater.inflate(R.layout.layout_classificacao, parent, false);
}
TextView colocacao = convertView.findViewById(R.id.texto1);
colocacao.setText(Integer.toString(classificacaoList.get(position).getColocacao()));
ImageView imagem = convertView.findViewById(R.id.imagem1);
imagem.setImageResource(classificacaoList.get(position).getImagem());
TextView nome = convertView.findViewById(R.id.texto2);
nome.setText(classificacaoList.get(position).getTime());
TextView pontos = convertView.findViewById(R.id.texto3);
pontos.setText(Integer.toString(classificacaoList.get(position).getPontos()));
return convertView;
}
This the layout "activity_atividade02" that have the ListView, and some others Text views that I won't display here.
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
This is the layout "layout_classificacao" that will be filled by the adapter
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp">
<TextView
android:id="#+id/texto1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:textColor="#android:color/black"
android:textSize="30sp" />
<ImageView
android:id="#+id/imagem1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_weight="1"
android:contentDescription="imagem do time"
app:srcCompat="#drawable/flamengo" />
<TextView
android:id="#+id/texto2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:textColor="#color/colorPrimary"
android:textSize="30sp" />
<TextView
android:id="#+id/texto3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:textColor="#android:color/black"
android:textSize="30sp" />
</LinearLayout>
And this is the main class "Atividade02"
that start everything
public class Atividade02 extends AppCompatActivity {
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_atividade02);
listView = findViewById(R.id.listView);
ArrayList<Classificacao> classificacaoArrayList = new ArrayList<>();
classificacaoArrayList.add(new Classificacao(1, 2,46));
classificacaoArrayList.add(new Classificacao(2, 1,42));
classificacaoArrayList.add(new Classificacao(3,0,38));
classificacaoArrayList.add(new Classificacao(4,3,35));
classificacaoArrayList.add(new Classificacao(5,5,33));
classificacaoArrayList.add(new Classificacao(6,4,33));
ArrayAdapter classificacaoAdapter = new ClassificacaoAdapter(this, classificacaoArrayList);
listView.setAdapter(classificacaoAdapter);
}
}
Resuming, the ListView isn't displaying the "ClassificacaoAdapter" and I want it to do it.
Make sure adapter has the method getItemcount() and it returns the classificacaoList.size(). It should not return 0;
Well... it was a pretty obvious problem, in the main layout activity_atividade02 there was a LinearLayout above the ListView that it's layout_height was set to match_parent and it was occupying the entire layout and not letting the ListView being displayed.
I test your code as you write and found an error here and it works normally but I comment imageView line because you don't define it in Classificacao class
an error here
TextView nome = convertView.findViewById(R.id.texto2);
nome.setText(classificacaoList.get(position).getTime());
setText() accept String only ..but you pass integer rather than String you can do that
nome.setText(""+classificacaoList.get(position).getTimee());
or use
Integer.toString( classificacaoList.get(position).getTimee() )
as you use in other lines
please add getCount() method in your ClassificacaoAdapter class, it is an override method. It will return the size of the list,if you will not override this it will return 0 as your list size.
public int getCount() {
return classificacaoList .size();
}

Changing TextView of individual items in a ListView

I am in the making of a shopping list using a ListView with custom items with the posibility of increasing the amount of that item and also decreasing the amount.
At the moment, I get the right amount of items when I load them in to the shopping list, as can seen in the image below:
the image of the ListView and problem
But the problem occurs when I am trying to increase/decrese the amount of each item by clicking the buttons, only the last item in the ListView gets updated by the clicks.
The reason for this is because i am re-declaring the TextView for each item, and the others (probably?) doesn't get stored anywhere. So i read about "setTag()" and "getTag()" and tried to implement but this didn't work either (maybe beacuse i did it wrong).
I am using a custom class called "Item" which stores each item and the amount of that item.
Otherwise, this is the custom adapter and the .xml
public class ShoppingListAdapter extends ArrayAdapter<Item> {
int amount;
TextView amountText;
private Context mContext;
int mResource;
public ShoppingListAdapter(#NonNull Context context, int resource, #NonNull ArrayList<Item> objects) {
super(context, resource, objects);
mContext = context;
mResource = resource;
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//get the item information
String name = getItem(position).getName();
String brand = getItem(position).getBrand();
int id = getItem(position).getId();
String img = getItem(position).getImg();
amount = getItem(position).getAmount();
//all info
Item item = new Item(name,id,brand,img);
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource,parent,false);
TextView tVName = (TextView) convertView.findViewById(R.id.textView2);
ImageView imgV = (ImageView) convertView.findViewById(R.id.imageView);
TextView tVId = (TextView) convertView.findViewById(R.id.textView3);
amountText = (TextView) convertView.findViewById( R.id.amountItem );
tVName.setText(name);
amountText.setText( String.valueOf( amount ) );
amountText.setTag(position);
Picasso.with(mContext).load(img).into(imgV); // tVBrand.setText(brand);
//tVId.setText(id);
//Buttons
Button addButton =(Button) convertView.findViewById(R.id.addValue);
Button subButton =(Button) convertView.findViewById(R.id.subValue);
addButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
getItem(position).incrementAmount();
//This gives the right position and the amount for all items
Log.d("ifIncreased", " " + getItem(position).getAmount());
Log.d("ifIncreased", position + "" );
TextView newText = (TextView) amountText.getTag(position);
newText.setText( String.valueOf( getItem(position).getAmount()));
}
} );
subButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
if(getItem(position).getAmount() == 1)
{
//TODO remove from list;
}
else{
getItem(position).decrementAmount();
Log.d("ifIncreased", position + "" );
amountText.setText( String.valueOf( getItem(position).getAmount()) );
}
}
} );
return convertView;
}
and the XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="100">
<ImageView
android:id="#+id/imageView"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_weight="33.3"
app:srcCompat="#mipmap/ic_launcher" />
<LinearLayout
android:layout_width="212dp"
android:layout_height="60dp"
android:layout_weight="33.3"
android:orientation="vertical">
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_below="#+id/textView2"
android:gravity=""
android:paddingLeft="10dp"
android:text="TextView3" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity=""
android:paddingLeft="10dp"
android:text="TextView2" />
</LinearLayout>
<LinearLayout
android:layout_width="112dp"
android:layout_height="60dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="#+id/amountItem"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="1"
android:textStyle="bold" />
<Button
android:id="#+id/addValue"
android:layout_width="40dp"
android:layout_height="33dp"
android:layout_gravity="center"
android:text="+"
android:textAlignment="center"
android:textSize="12sp" />
<Button
android:id="#+id/subValue"
android:layout_width="40dp"
android:layout_height="33dp"
android:layout_gravity="center"
android:text="–"
android:textAlignment="center"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
So- since I am having the right values in the onClick functions, my question is, how can I change each TextView (the amount of that item) from the items in the full list?
Try this to update single value into adapter.. make public method and that method called into fragment or activity when you updated any value and refresh adapter.
/**
* this method used to update list item when broad cast received.
* #param percentage
* #param position
*/
public void updateProgress(double percentage, final int position) {
feedBackVoList.get(position).setPercentage(percentage);
notifyItemChanged(position);
}
after that updated value set into textview when you called notifyItemChanged(position) reset again that row or refresh that row.

i want to add two items in this listview from mysql

I am struggling from Listview , how to add two value in this Listview , i am using SimpleAdapter but i can't add two value , Listview shows only one item from database , how to add two values from mysql database . How can i add two values ?
//this is my layout file
//main activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="0dp">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="New Class :"
android:textSize="17dp"
android:fontFamily="serif"
android:textColor="#000"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1"/>
<Spinner
android:id="#+id/new_class"
style="#style/Platform.Widget.AppCompat.Spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:background="#drawable/spinner_background"
android:popupBackground="#fff"
android:fontFamily="serif"
android:layout_marginRight="10dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:choiceMode="multipleChoice"
android:focusable="false"/>
</LinearLayout>
</LinearLayout>
//this is my row activity file for custom layout
<?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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/thumbImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="sample text"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceMedium" />
<CheckedTextView
android:id="#+id/itemCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:focusable="false"
android:focusableInTouchMode="false"/>
</LinearLayout>
</RelativeLayout>
//this is my code
listview.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
sparseBooleanArray = listview.getCheckedItemPositions();
String ValueHolder = "" ;
int i = 0 ;
while (i < sparseBooleanArray.size()) {
if (sparseBooleanArray.valueAt(i)) {
ValueHolder += data4.get(sparseBooleanArray.keyAt(i)) + ",";
}
i++ ;
}
ValueHolder = ValueHolder.replaceAll("(,)*$", "");
Toast.makeText(MainActivity.this, ValueHolder, Toast.LENGTH_LONG).show();
}
});
how to create custom array adapter please help me
just use custom array adapter as shown below
this is my adapter class
public class ItemAdapter extends ArrayAdapter<User> {
// declaring our ArrayList of items
private ArrayList<User> objects;
/* here we must override the constructor for ArrayAdapter
* the only variable we care about now is ArrayList<User> objects,
* because it is the list of objects we want to display.
*/
public ItemAdapter(Context context, int textViewResourceId, ArrayList<User> objects) {
super(context, textViewResourceId, objects);
this.objects = objects;
}
/*
* we are overriding the getView method here - this is what defines how each
* list item will look.
*/
public View getView(int position, View convertView, ViewGroup parent){
// assign the view we are converting to a local variable
View v = convertView;
// first check to see if the view is null. if so, we have to inflate it.
// to inflate it basically means to render, or show, the view.
if (v == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_item, null);
}
/*
* Recall that the variable position is sent in as an argument to this method.
* The variable simply refers to the position of the current object in the list. (The ArrayAdapter
* iterates through the list we sent it)
*
* Therefore, i refers to the current User object.
*/
User i = objects.get(position);
if (i != null) {
// This is how you obtain a reference to the TextViews.
// These TextViews are created in the XML files we defined.
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView ttd = (TextView) v.findViewById(R.id.toptextdata);
TextView mt = (TextView) v.findViewById(R.id.middletext);
TextView mtd = (TextView) v.findViewById(R.id.middletextdata);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);
TextView btd = (TextView) v.findViewById(R.id.desctext);
// check to see if each individual textview is null.
// if not, assign some text!
if (tt != null){
tt.setText("Name: ");
}
if (ttd != null){
ttd.setText(i.getName());
}
if (mt != null){
mt.setText("Price: ");
}
if (mtd != null){
mtd.setText("$" + i.getPrice());
}
if (bt != null){
bt.setText("Details: ");
}
if (btd != null){
btd.setText(i.getDetails());
}
}
// the view must be returned to our activity
return v;
}
}
set an instance of custom adapter in your list view like this
ItemAdapter itemAdapter = new ItemAdapter(...);
listView.setAdapter(itemAdapter)
if it helped please verify the answer

Populating a ListView with items from an array in Java

I have 4 fields on a custom row layout for a listview. I have 4 fields in my array that I want to map to those 4 fields on the listview:
cat_ID_PK
cat_name
cat_amount
is_recurring
I have no idea how to correctly do that. Here's what I have so far:
private void loadListView(Expenses[] mExpenseArray) {
//This code will write the "name" variable correctly to the logcat, so I know I'm
getting the right values in my array.
String name = mExpenseArray[0].getCatName();
Log.v("log_tag", name);
ArrayAdapter<Expenses> adapter = new ArrayAdapter<Expenses>(getApplicationContext(), R.layout.list_row, R.id.catName, mExpenseArray);
final ListView listView = (ListView) findViewById(R.id.list);
listView.setAdapter(adapter);
}
This code only populates R.id.catName, but when it populates it, it looks like this: mypackage#8ed455 (or something similar). None of the other fields are populated at all, which I'm guessing has to do with the 3rd parameter in my ArrayAdapter being R.id.catName. However, if I take this parameter out I get this error:
java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
Here is the code for my custom row layout:
<?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="wrap_content"
android:background="#drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
<TextView
android:id="#+id/catName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_centerVertical="true"
android:paddingBottom ="10dip"
android:text="#string/catName"
android:textColor="#040404"
android:textSize="25dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/catAmount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="27dip"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:paddingBottom ="10dip"
android:text="$45.00"
android:textColor="#040404"
android:textSize="25dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/catType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/catName"
android:layout_alignLeft="#+id/catName"
android:paddingTop="5dip"
android:layout_centerHorizontal="true"
android:text="#string/catType"
android:textColor="#343434"
android:textSize="15dip" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="catID"
android:id="#+id/catID"
android:layout_alignBottom="#+id/catType"
android:layout_toRightOf="#+id/catType"
android:layout_toEndOf="#+id/catType"
android:layout_marginLeft="27dp"
android:visibility="invisible" />
</RelativeLayout>
How can I correctly map my 4 array fields to my ListView?
make a custom adapter like this and then assign the values to the text views
pass array like this to adapter
UserList disadpt = new UserList(HomePage.this, mEmployeeList);
userList.setAdapter(disadpt);
then in adapter do this ..
public class UserList extends BaseAdapter
{
private Context mContext;
private ArrayList<Employee> items;
public UserList(Context c, ArrayList<Employee> items)
{
this.mContext = c;
this.items = items;
}
public int getCount() {
return this.items.size();
}
public Object getItem(int position) {
return this.items.get(position);
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(int pos, View child, ViewGroup arg2) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.listcell, null);
mHolder = new Holder();
//mHolder.txt_id = (TextView) child.findViewById(R.id.txt_id);
mHolder.txt_fName = (TextView) child.findViewById(R.id.txt_fName);
mHolder.txt_lName = (TextView) child.findViewById(R.id.txt_lName);
mHolder.txt_userName = (TextView) child.findViewById(R.id.txt_userName);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
Employee employee = this.items.get(pos);
ArrayList<String> employeeInfo = new ArrayList<String>();
employeeInfo.add(employee.employeeId);
employeeInfo.add(employee.firstName);
employeeInfo.add(employee.lastName);
mHolder.Details.setTag(employeeInfo);
mHolder.txt_fName.setText(employee.firstName + " " + employee.lastName);
mHolder.txt_userName.setText(employee.emailId);
return child;
}
public class Holder
{
//TextView txt_id;
TextView txt_fName;
TextView txt_lName;
TextView txt_userName;
Button Details;
}
}
hope this helps ...
Create String type of array Adapter and use-
adapter.add(mExpenseArray[0].getCatName());
by using any loop.

Android: Why is onItemClick for my ListView using ArrayAdapter not working?

I have a ListView made up of a LinearLayout and some elements within. It's driven by a custom Adapter that extends ArrayAdapter>. For some reason it's not getting called when I click on of of the displayed items. Nothing happens in logcat. No error, no Log, nothing.
I've read a number of similar questions, and tried to implement the solutions, but that doesn't seem to be my issue. I tried onItemClickListener not firing on custom ArrayAdapter and Listview onitemclick listener is not working and OnItemClick not responding to clicks
Here's my activity code:
ratingAdapter = new RatingAdapter(this, RatingRecord);
ratingListView = (ListView) findViewById(R.id.ratingsListView);
ratingListView.setAdapter(ratingAdapter);
ratingListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.d("Ratings update", "Clicked button for " + RatingRecord.get(i).get(1));
RateRestaurant(RatingRecord.get(i));
}
});
Here's my item xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:clickable="true"
android:id="#+id/ratings_row"
style="#android:style/Widget.Button"
android:descendantFocusability="blocksDescendants"
android:focusable="true">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_weight="2"
android:id="#+id/rating_name"
android:focusable="false"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:adjustViewBounds="true"
android:paddingRight="5dp"
android:id="#+id/rating_icon"
android:focusable="false"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_weight="1"
android:id="#+id/rating_date"
android:gravity="center_horizontal"
android:focusable="false"/>
</LinearLayout>
Here's the ListView layout from the main activity:
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="#+id/ratingsListView"/>
Here's the meat of the adapter RatingAdapter:
public RatingAdapter(Context context, ArrayList<ArrayList<String>> inValues) {
super(context, R.layout.ratings_row, inValues);
this.context = context;
ratingList = CsvUtil.fromCsvTable(context.getString(R.string.Ratings_OptionsList));
}
private ViewHolder(View c, Integer n, Integer i, Integer d) {
NameView = (TextView)c.findViewById(n);
IconView = (ImageView)c.findViewById(i);
DateView = (TextView)c.findViewById(d);
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
ArrayList<String> record = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder vh;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.ratings_row, parent, false);
vh = new ViewHolder(convertView,R.id.rating_name,R.id.rating_icon,R.id.rating_date);
convertView.setTag(vh);
} else {
vh = (ViewHolder)convertView.getTag();
}
// Lots of data calculation and populating ViewHolder elements
return convertView;
}
Nothing happens. Like I said, no log or event or error. What have I done wrong?
set on click on your convertview in adapter getView() method.
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Ratings update", "Clicked button for " + RatingRecord.get(i).get(1));
RateRestaurant(RatingRecord.get(i));
}
}
Answer provided by Haresh in the comments.
"please try to remove this line style="#android:style/Widget.Button" from your list item layout"
I used the style Widget.Button to give me the look of a button though the ListView already provided the click through functionality. However the style did more than change the look. It also overrode the clicking function. To get the effect I wanted without the side effects, I just set the background using:
android:background="#android:drawable/btn_default"

Categories

Resources