I have read other topics and I still have problem. setOnItemClickListener should be in Adapter class like below or in "MainActivity" class?
If is in Adapter class It can't do right reference to layout.
Error logcat:
Attempt to invoke virtual method 'void
android.widget.ListView.setOnItemClickListener(android.widget.AdapterView$OnItemClickListener)' on a null object reference
ListAdapter.java
public class ListAdapter extends CursorAdapter {
public ListAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
return LayoutInflater.from(context).inflate(R.layout.items, parent, false);
}
#Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find fields to populate in inflated template
TextView txt1 = (TextView) view.findViewById(R.id.TitleLabel);
TextView txt2 = (TextView) view.findViewById(R.id.SecondLabel);
TextView txt3 = (TextView) view.findViewById(R.id.ThirdLabel);
// Extract properties from cursor
String name = cursor.getString(1);
txt1.setText(name);
ListView listview = (ListView) v.findViewById(R.id.listView);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
final int position, final long id) {
final String itemId = cursor.getString(cursor.getColumnIndex("_id"));
Log.i("Activity", "Cursor: " + cursor + " + " + position + " + id " + id + " ITEMID: " + itemId);
// final String item = (String) parent.getItemAtPosition(position);
view.animate().setDuration(500).alpha(0)
.withEndAction(new Runnable() {
#Override
public void run() {
// it was for SimpleCursorAdapter
listview.remove(item);
helper.deleteitem(id+1);
helper.deleteItemByName(item);
adapter.notifyDataSetChanged();
view.setAlpha(1);
}
});*/
}
});
}
}
items.xml layout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
>
<ImageView
android:id="#+id/postThumb"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="#drawable/ic_launcher"
android:scaleType="centerCrop"
android:layout_marginRight="5dp"/>
<TextView
android:id="#+id/TitleLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/postThumb"
android:layout_toRightOf="#id/postThumb"
android:maxLines="1"
android:text="Lorem Ipsum 1 line"
android:textIsSelectable="false"
android:textSize="16sp"
android:ellipsize="end"/>
<TextView
android:id="#+id/SecondLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:textSize="12dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/postThumb"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<TextView
android:id="#+id/ThirdLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignBottom="#id/postThumb"
android:layout_toRightOf="#id/postThumb"
android:maxLines="1"
android:textSize="11dp"
/>
</RelativeLayout>
Try to have setOnItemClickListener in oyur MainActivity but if you wish to use in your Adapter class then use setOnclickListener method of parent lauout of R.layout.items
Because in bindView each items are treated as single item.
Edited
Add id in Relative layout
android:id="#+id/myRelativelayout"
In Adatpter class
RelativeLayout rl =(RelativeLayout) view.findViewById(R.id.myRelativelayout);
implement r1.setOnClickListener and add your code.
Related
I have a Fragment class that can display everything in my database in a ListView, and I have an inner class that extends SimpleCursorAdapter to use buttons within my ListView.
So in each element of my list view, I have several TextView's and 2 button. With my following code, I can use a button listener for a button inside my ListView. But inside my listener, I want to get the content of the TextView inside the same element that the button I click on. But When I click on a button to display my TextView, it display the last element of my ListView and I don't know why !
For example if I have 3 elements in my ListView like this :
_id = 1, name = "bob"
_id = 2, name = "john"
_id = 3, name = "bobby"
Each of these element are displayed with a button to display there ID, but if I click on the button inside bob, I get "id = 3". Same for john and bobby. And if I had a new element, I get his ID
My listener is in the bind function in my inner class MySimpleCursorAdapter.
Here is my Fragment Class :
public class ViewCardEditor extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
public static final String authority = "com.example.jean.cartememoire.CardContentProvider";
public String[] from;
public final int[] to = {R.id.idList, R.id.themeList, R.id.questionList, R.id.reponseList, R.id.difficultList};
StockCard stock;
ViewGroup container;
ListView listView;
MySimpleCursorAdapter adapter;
private ArrayList<String> data = new ArrayList<String>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup c,
Bundle savedInstanceState) {
container = c;
View view = inflater.inflate(R.layout.fragment_view_card_editor, container, false);
stock = new StockCard(c.getContext());
from = new String[]{stock._ID,
stock.THEME,
stock.QUESTION,
stock.REPONSE,
stock.DIFFICULTE};
// Inflate the layout for this fragment
if (container != null) {
container.removeAllViews();
}
//listView.setAdapter(new MyListAdapter(container.getContext(), R.layout.card_stock, data));
//View view_cs = LayoutInflater.from(container.getContext()).inflate(R.layout.card_stock, null);
//Supprimer = (Button) view_cs.findViewById(R.id.buttonDelete);
//Modifier = (Button) view_cs.findViewById(R.id.buttonModifier);
databaseView(view);
return view;
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri.Builder builder = new Uri.Builder();
Uri uri = builder.scheme("content").authority(authority)
.appendPath(stock.STOCK_TABLE).build();
return new CursorLoader(container.getContext(), uri, from,
null, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
public void databaseView(View view)
{
ArrayList<String> list;
Cursor cursor = stock.getData();
listView = (ListView) view.findViewById(R.id.listView);
adapter = new MySimpleCursorAdapter(container.getContext(), R.layout.card_stock, null, from, to,0);
listView.setAdapter(adapter);
LoaderManager manager = getLoaderManager();
manager.initLoader(0, null, this);
}
public void deleteOneCard(int id)
{
Uri.Builder builder = new Uri.Builder();
builder.scheme("content").authority(authority).appendPath(stock.STOCK_TABLE);
ContentUris.appendId(builder, id);
Uri uri = builder.build();
ContentResolver resolver = container.getContext().getContentResolver();
resolver.delete(uri, null, null);
}
private class MySimpleCursorAdapter extends SimpleCursorAdapter
{
ViewHolder vh;
public MySimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
public View newView(Context _context, Cursor _cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) _context.getSystemService(_context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.card_stock, parent, false);
vh = new ViewHolder();
vh.idList = (TextView) view.findViewById(R.id.idList);
vh.themeList = (TextView) view.findViewById(R.id.themeList);
vh.questionList = (TextView) view.findViewById(R.id.questionList);
vh.reponseList = (TextView) view.findViewById(R.id.reponseList);
vh.difficulteList = (TextView) view.findViewById(R.id.difficultList);
vh.Supprimer = (Button) view.findViewById(R.id.buttonDelete);
vh.Modifier = (Button) view.findViewById(R.id.buttonModifier);
view.setTag(vh);
return view;
}
public void bindView(View view, Context Context, Cursor cursor) {
vh.idList.setText(cursor.getString(cursor.getColumnIndex(stock._ID)));
vh.themeList.setText(cursor.getString(cursor.getColumnIndex(stock.THEME)));
vh.questionList.setText(cursor.getString(cursor.getColumnIndex(stock.QUESTION)));
vh.reponseList.setText(cursor.getString(cursor.getColumnIndex(stock.REPONSE)));
vh.difficulteList.setText(cursor.getString(cursor.getColumnIndex(stock.DIFFICULTE)));
vh.Supprimer.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
int id = Integer.parseInt(vh.idList.getText().toString());
Toast.makeText(container.getContext(), "bouton delete : "+id, Toast.LENGTH_LONG).show();
//Here everytime I hit the button, the last ID i put on the listView is displayed, no matter what Supprimer button I click
}
});
}
}
public class ViewHolder
{
Button Supprimer, Modifier;
TextView idList, themeList, questionList, reponseList, difficulteList;
}
}
And here is my layout for my TextView :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="#+id/relativeList"
android:descendantFocusability="blocksDescendants">
<TextView
android:text="#string/difficult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView8"
android:layout_below="#+id/textView7"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="29dp" />
<TextView
android:text="#string/r_ponse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView7"
android:layout_marginTop="20dp"
android:layout_below="#+id/textView6"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/idList"
android:layout_alignParentTop="true"
android:layout_alignLeft="#+id/themeList"
android:layout_alignStart="#+id/themeList"
tools:ignore="HardcodedText" />
<TextView
android:text="Question :"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView6"
android:layout_marginTop="14dp"
android:layout_below="#+id/textView4"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
tools:ignore="HardcodedText" />
<TextView
android:text="#string/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView3"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/textView4"
android:layout_alignEnd="#+id/textView4" />
<TextView
android:text="Thème :"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textView4"
android:layout_below="#+id/textView3"
android:layout_alignRight="#+id/textView6"
android:layout_alignEnd="#+id/textView6"
tools:ignore="HardcodedText" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/textView6"
android:id="#+id/questionList"
android:layout_toRightOf="#+id/themeList"
android:layout_toEndOf="#+id/themeList" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView8"
android:layout_alignLeft="#+id/questionList"
android:layout_alignStart="#+id/questionList"
android:id="#+id/reponseList" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/textView8"
android:layout_alignRight="#+id/reponseList"
android:layout_alignEnd="#+id/reponseList"
android:id="#+id/difficultList"
android:layout_toEndOf="#+id/reponseList"
android:layout_toRightOf="#+id/reponseList" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/themeList"
android:layout_marginLeft="33dp"
android:layout_marginStart="33dp"
tools:ignore="HardcodedText"
android:layout_below="#+id/idList"
android:layout_toRightOf="#+id/textView8"
android:layout_toEndOf="#+id/textView8" />
<Button
android:text="#string/supprimerb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="#+id/buttonDelete"/>
<Button
android:text="#string/modifierB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/buttonModifier"
android:layout_alignTop="#+id/questionList"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignLeft="#+id/buttonDelete"
android:layout_alignStart="#+id/buttonDelete" />
</RelativeLayout>
Thank you for help !
Probably vh.idList is containing last item view which is provided by last call of newView .
Get clicked row item id using findViewById and v parameter of onClick method:
public void onClick(View v) {
View parentView = (View)v.getParent();
TextView idList = parentView.findViewById(R.id.idList);
int id = Integer.parseInt(idList.getText().toString());
...
}
I am new in android. I want to show the data that I get from Database into ListView.
For now I can show only a single data.
How to show multiple data into custom ListView?
Here's my MainActivity.class
DatabaseHandler db = new DatabaseHandler(this);
/**
* CRUD Operations
* */
Log.d("Reading: ", "Reading all contacts..");
List <AllItem> allItems = new ArrayList<AllItem>();
allItems = db.getAllAccommodations();
ArrayList <String> allItems2 = new ArrayList<String>();
for (AllItem cn : allItems) {
allItems2.add(cn.getItem_name());
allItems2.add(cn.getAreaNAme());
}
ArrayAdapter <String> adapter = new ArrayAdapter <String> (this, android.R.layout.simple_list_item_1,allItems2);
listview.setAdapter(adapter);
I have my own custom ListView like this
Acco.xml
<ListView
android:id="#+id/listAccommodation"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="8"
android:layout_marginLeft="7dip"
android:layout_marginRight="7dip"
android:background="#color/white"
android:divider="#color/black90"
android:dividerHeight="5.0sp"
android:listSelector="#color/black30" >
</ListView>
AccoLayout.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:paddingTop="10dip"
android:paddingBottom="10dip" >
<TextView
android:id="#+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/area_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_below="#+id/item_name" />
</RelativeLayout>
Is there anyone can help me with this?
You need to create CustomAdapter class for this.
Use your listview as it is.
<ListView
android:id="#+id/listAccommodation"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="8"
android:layout_marginLeft="7dip"
android:layout_marginRight="7dip"
android:background="#color/white"
android:divider="#color/black90"
android:dividerHeight="5.0sp"
android:listSelector="#color/black30" >
</ListView>
And your custom Listview also.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:paddingTop="10dip"
android:paddingBottom="10dip" >
<TextView
android:id="#+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/area_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_below="#+id/item_name" />
</RelativeLayout>
Create your custom adapter class and pass data to this class.
adapter = new ListAdapter(this, allItems2);
adapter.notifyDataSetChanged();
listview.setAdapter(adapter);
Here is CustomAdapter class.
public class ListAdapter extends BaseAdapter {
public ListAdapter(Activity a, List <AllItem> allItems) {
activity = a;
data = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.AccoLayout, null);
TextView itemName = (TextView)vi.findviewById(R.id.item_name);
TextView areaName = (TextView)vi.findviewById(R.id.area_name);
// Set your data here
itenName.setText(data.get(position));//like this
return vi;
}
}
I assume that your allItems2 list has a pattern like itemName0, areaName0, itemName1, areaName1, itemName2.. etc. Then, you can write a custom adapter like this.
public class CustomAdapter extends ArrayAdapter<String> {
private final Activity context;
private final List<String> items;
public CustomAdapter (Activity context, List<String> items) {
super(context, R.layout.AccoLayout, items);
this.context = context;
this.items= items;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.AccoLayout, null, true);
TextView itemName = (TextView) rowView.findViewById(R.id.item_name);
TextView areaName= (TextView) rowView.findViewById(R.id.area_name);
itemName.setText(items.get(2*position));
areaName.setText(items.get(2*position + 1));
return rowView;
}
}
Then call it from your main activity;
CustopAdapter adapter = new CustomAdapter (MainActivity.this, allItems2);
listview.setAdapter(adapter);
Also, by Android's convention, try not to use uppercase letters in XML file names to prevent any complication. You may change to acco_layout.xml.
Consider this to be your Cursor: after you fetch from DB
Cursor mCur = db.getAllAccommodations();
in onCreate:
CurAdapter Cur = new CurAdapter(getActivity(), mCur,0);
final ListView lv = (ListView)findViewById(R.id.listAccommodation);
lv.setFastScrollEnabled(true);
lv.setAdapter(Cur);
Then Make a Subclass:
private class CurAdapter extends CursorAdapter{
public CurAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView tv = (TextView) view.findViewById(R.id.item_name);
TextView tv1 = (TextView) view.findViewById(R.id.area_name);
String item = (cursor.getString(cursor.getColumnIndexOrThrow("ColumnName1")));
String area = dateConvert(cursor.getString(cursor.getColumnIndexOrThrow("ColumnName2")));
tv1.setText(item);
tv.setText(area);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.AccoLayout, null);
return view;
}
}
Where R.layout.AccoLayout is your "listview row" layout, for example:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dip"
android:paddingLeft="10dip"
android:paddingTop="10dip" >
<TextView
android:id="#+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/area_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/item_name"
android:textSize="14sp" />
</RelativeLayout>
I have a custom cursor adapter CAdapter having the following lines of code:
public class CAdapter extends CursorAdapter {
public CAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView titleTV = (TextView) view.findViewById(R.id.listTitle);
titleTV.setText("#"+cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1)))+" "+
cursor.getString(cursor.getColumnIndex(cursor.getColumnName(2))));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View retView = inflater.inflate(R.layout.row_item_layout, parent, false);
return retView;
}
}
row_item_layout.xml file is
<?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">
<TextView
android:id="#+id/listTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="2dp"
android:layout_toRightOf="#+id/heartIV"
android:focusable="false"
android:gravity="center_vertical"
android:text="Example application"
android:textSize="26sp"
android:paddingBottom="3dp"/>
<ImageView
android:id="#+id/heartIV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/listTitle"
android:src="#drawable/heart"
android:paddingRight="5dp"
android:paddingLeft="2dp"/>
</RelativeLayout>
The activity FavListActivity displays the list. Its layout file is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.xkcdreader.FavListActivity"
tools:ignore="MergeRootFrame" >
<ListView
android:id="#+id/favL"
android:layout_width="match_parent"
android:layout_height="452dp"
android:layout_alignParentBottom="true"
android:layout_below="#+id/headingTV" >
</ListView>
<TextView
android:id="#+id/headingTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="8dp"
android:text="Favourites"
android:textSize="25dp" />
</RelativeLayout>
Following is a section of code from FavListActivity
listView = (ListView) findViewById(R.id.favL);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("App", "clicked on item: " + position);
TextView listTV=(TextView) view.findViewById(R.id.titleTV);
Log.d("App",listTV.getText().toString());
}
});
On running this I get NullPointerException at the line Log.d("App",listTV.getText().toString()); The list does not having any null textview. I can't figure out the problem. Please help
you should use getItemAtPosition:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor mycursor = (Cursor)parent.getItemAtPosition(position);
}
});
and use myCursor to access your data.
Try this..
Your TextView id is listTitle but you have mentioned as titleTV change that and try it.
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d("App", "clicked on item: " + position);
TextView listTV=(TextView) view.findViewById(R.id.listTitle);
Log.d("App",listTV.getText().toString());
}
});
There is no TextView in row_item_layou.xml with id titleTV. So when you initialize you end up getting NUllPointerException.
Change this
TextView listTV=(TextView) view.findViewById(R.id.titleTV);
to
TextView listTV=(TextView) view.findViewById(R.id.listTitle);
since you have
<TextView
android:id="#+id/listTitle" // id is listTitle
Although your NPE can be solved as above you are better off using blackbet's answer
Cursor mycursor = (Cursor)parent.getItemAtPosition(position);
Then get the String using the mycursor.
I've a ListView that I populate with a SimpleCursorAdapter. For each item in my list i've, in this order: TextView > RatingBar > TextView > ImageView. I want to add a button on the ImageView but I dont know how to this...
Where I populate the ListView:
adapter = new SimpleCursorAdapter(this, R.layout.beerdrunk, cursor,
new String[] { "beers", "notes", "numbers" }, new int[] {
R.id.champName, R.id.champNote, R.id.champDrunk });
adapter.setViewBinder(binder);
list = (ListView) findViewById(R.id.listMyBeers);
list.setItemsCanFocus(true);
list.setOnItemClickListener(onClickBeer);
list.setAdapter(adapter);
The OnItemClickListener:
private OnItemClickListener onClickBeer = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
System.out.println(""+ arg0);
System.out.println(""+ arg1);
System.out.println(""+arg2);
Intent newActivity = new Intent(MyBeers.this, DetailsBeer.class);
newActivity.putExtra("com.example.checkmybeer.DetailsBeer", ""
+ arg3);
startActivityForResult(newActivity, 0);
}
};
And the XML for beerdrunk:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/champName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="130"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:maxLines="3"
android:padding="5dp"
android:paddingRight="20dp"
android:singleLine="false"
android:text="#string/beerBook"
android:textColor="#color/black1"
android:textSize="20sp"
android:textStyle="bold" >
</TextView>
<View
android:layout_width="1.5dip"
android:layout_height="fill_parent" />
<RatingBar
android:id="#+id/champNote"
style="#style/beerRatingSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:isIndicator="true"
android:numStars="5"
android:layout_margin="1.5dp"
android:rating="5"
android:stepSize="0.10" >
</RatingBar>
<View
android:layout_width="1.5dip"
android:layout_height="fill_parent" />
<TextView
android:id="#+id/champDrunk"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="30"
android:gravity="right|center_vertical"
android:padding="5dp"
android:layout_marginLeft="5dp"
android:text="200"
android:textColor="#color/black1"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:layout_width="1.5dip"
android:layout_height="fill_parent" />
<ImageView
android:id="#+id/champPlusone"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_margin="5dp"
android:layout_weight="30"
android:gravity="right|center_vertical"
android:clickable="false"
android:src="#drawable/plus2" />
</LinearLayout>
I've tried something like:
if(arg2 instanceof ImageView){
//do some stuff
}
But it does not work... How can i do to know which view is clicked inside my "row" ?
If you want to click on an image, use an ImageButton instead of an ImageView.
You can then set the onClick attribute on the button that calls a method in your Activity.
Extend a SimpleCursorAdapter and in the bindView method add onClick listeners for each button. (Maybe make it call a method in your activity ... public void buttonClicked(int position, View v)... so you know which row and which view was clicked.
Here is an example implementation of CursorAdapter you could use.
class CustomCursorAdapter extends CursorAdapter{
LayoutInflater inflater;
public CustomCursorAdapter(Context context, Cursor c, int flags){
super(context,c,flags);
inflater = LayoutInflater.from(context);
}
#Override
public void bindView(View view, Context context, Cursor cursor){
int row_id = cursor.get('_id'); //Your row id (might need to replace)
ImageButton button = (ImageButton) view.findViewById(R.id.champPlusone);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
//ADD STUFF HERE you know which row is clicked. and which button
}
});
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent){
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.beerdrunk, parent, false);
bindView(v,context,cursor);
return v;
}
}
;)
Listview with checkbox and CustomCursorAdapter
In ListActivity.java
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
ListView listView = (ListView) findViewById(R.id.lists);
listView.setItemsCanFocus(false);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
//create Cursor called cursor
listAdapter = new DetailListAdapter(this, cursor);
getLoaderManager().initLoader(LOADER_ID, null, this);
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3)
{
//want to call startactionmode with class implementing ListView.MultiChoiceModeListener
}
});
}
In DetailListAdapter.java
public class DetailListAdapter extends CursorAdapter
{
private Context context;
private ArrayList<Boolean> checked = new ArrayList<Boolean>();
private LayoutInflater mLayoutInflater;
public DetailListAdapter(Context context, Cursor c)
{
super(context, c);
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
{
View v = mLayoutInflater.inflate(R.layout.list_item, parent, false);
return v;
}
#Override
public void bindView(View v, Context context, Cursor c)
{
final View view = v;
final int position = c.getInt(0);
String data = c.getString(c.getColumnIndexOrThrow("DATA"));
/**
* Next set the name of the entry.
*/
TextView list_text = (TextView) view.findViewById(R.id.listitemtext);
CheckBox checkbox_text = (CheckBox) view.findViewById(R.id.listitemcheckbox);
list_text.setText(data);
checked.add(position - 1, false);
checkbox_text.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if (isChecked)
{
view.setBackgroundColor(Color.GRAY);
checked.set(position - 1, true);
} else
{
view.setBackgroundColor(Color.BLACK);
checked.set(position - 1, false);
}
}
});
checkbox_text.setChecked(!checkbox_text.isChecked());
}
}
The list row xml is,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants">
<CheckBox
android:id="#+id/check1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="20dp"
android:focusable="false"
/>
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/check1"
android:layout_toRightOf="#+id/check1"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/text1"
android:layout_alignBottom="#+id/text1"
android:layout_marginLeft="20dp"
android:layout_toRightOf="#+id/text1"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="#+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/text2"
android:layout_below="#+id/text1"
android:layout_toRightOf="#+id/check1"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
</RelativeLayout>
When I click on list item in emulator, checkbox is checked and row turns into gray.
But onitemclick is not getting called. I do have android:focusable="false" and android:focusableInTouchMode="false" on all items in layout which creates a row in list.
I want checkbox to be checked and menu to be displayed at top containing actions that can be perfomed on that selected list item..
Two OnClickListeners cannot be called from one touch event. As you see, the first listener's onCheckedChanged() method consumes the event preventing it from reaching the onItemClick() method.
I recommend using a Checkable layout in your rows that will maintain the check state for you and changing your adapter's getView() to set the appropriate background color on account of the view recycler.
(Post your XML in you question if you need help with this.)