I need to save the state of my CheckBox, they are inside of a Spinner, and every time I open the Spinner all of CheckBox is unchecked.
AdmListagem.java
final String[] select_qualification = {
"Todos", "1", "2", "3", "4",
"5", "6"};
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayList<StateVO> listVOs = new ArrayList<>();
for (int i = 0; i < select_qualification.length; i++) {
StateVO stateVO = new StateVO();
stateVO.setTitle(select_qualification[i]);
stateVO.setSelected(false);
listVOs.add(stateVO);
}
MyAdapter myAdapter = new MyAdapter(AdmListagem.this, 0,
listVOs);
spinner.setAdapter(myAdapter);
spinner_item2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="25dp"
android:paddingTop="10dp"
android:paddingRight="10dp"
android:paddingBottom="10dp"
android:textSize="16dp"
android:textColor="#000000"
android:background="#drawable/spinner_item_border" />
<CheckBox
android:id="#+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
MyAdapter.java
public class MyAdapter extends ArrayAdapter<StateVO> {
private Context mContext;
private ArrayList<StateVO> listState;
private MyAdapter myAdapter;
private boolean isFromView = false;
String[] values;
Boolean[] checkedStatus;
public MyAdapter(Context context, int resource, List<StateVO> objects) {
super(context, resource, objects);
this.mContext = context;
this.listState = (ArrayList<StateVO>) objects;
this.myAdapter = this;
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(final int position, View convertView,
ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(mContext);
convertView = layoutInflator.inflate(R.layout.spinner_item2, null);
holder = new ViewHolder();
holder.mTextView = (TextView) convertView
.findViewById(R.id.text);
holder.mCheckBox = (CheckBox) convertView
.findViewById(R.id.checkbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mTextView.setText(listState.get(position).getTitle());
// To check weather checked event fire from getview() or user input
isFromView = true;
holder.mCheckBox.setChecked(listState.get(position).isSelected());
isFromView = false;
if ((position == 0)) {
holder.mCheckBox.setVisibility(View.INVISIBLE);
} else {
holder.mCheckBox.setVisibility(View.VISIBLE);
}
holder.mCheckBox.setTag(position);
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int getPosition = (Integer) buttonView.getTag();
String t = String.valueOf(getPosition);
Toast.makeText(mContext, t, Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
private class ViewHolder {
private TextView mTextView;
private CheckBox mCheckBox;
}
}
StateVO.java
public class StateVO {
private String title;
private boolean selected;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
When I run the code open the Spinner check what I want, touch on screen to close the Spinner, open it again and all the CheckBox is unchecked.
I want to create a custom adapter for my list view. Is there any article that can walk me through how to create one and also explain how it works?
public class ListAdapter extends ArrayAdapter<Item> {
private int resourceLayout;
private Context mContext;
public ListAdapter(Context context, int resource, List<Item> items) {
super(context, resource, items);
this.resourceLayout = resource;
this.mContext = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(mContext);
v = vi.inflate(resourceLayout, null);
}
Item p = getItem(position);
if (p != null) {
TextView tt1 = (TextView) v.findViewById(R.id.id);
TextView tt2 = (TextView) v.findViewById(R.id.categoryId);
TextView tt3 = (TextView) v.findViewById(R.id.description);
if (tt1 != null) {
tt1.setText(p.getId());
}
if (tt2 != null) {
tt2.setText(p.getCategory().getId());
}
if (tt3 != null) {
tt3.setText(p.getDescription());
}
}
return v;
}
}
This is a class I had used for my project. You need to have a collection of your items which you want to display, in my case it's <Item>. You need to override View getView(int position, View convertView, ViewGroup parent) method.
R.layout.itemlistrow defines the row of the ListView.
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="fill_parent">
<TableRow android:layout_width="fill_parent"
android:id="#+id/TableRow01"
android:layout_height="wrap_content">
<TextView android:textColor="#FFFFFF"
android:id="#+id/id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="id" android:textStyle="bold"
android:gravity="left"
android:layout_weight="1"
android:typeface="monospace"
android:height="40sp" />
</TableRow>
<TableRow android:layout_height="wrap_content"
android:layout_width="fill_parent">
<TextView android:textColor="#FFFFFF"
android:id="#+id/categoryId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="categoryId"
android:layout_weight="1"
android:height="20sp" />
<TextView android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
android:textColor="#FFFFFF"
android:gravity="right"
android:id="#+id/description"
android:text="description"
android:height="20sp" />
</TableRow>
</TableLayout>
In the MainActivity define ListViewlike this,
ListView yourListView = (ListView) findViewById(R.id.itemListView);
// get data from the table by the ListAdapter
ListAdapter customAdapter = new ListAdapter(this, R.layout.itemlistrow, List<yourItem>);
yourListView .setAdapter(customAdapter);
I know this has already been answered... but I wanted to give a more complete example.
In my example, the ListActivity that will display our custom ListView is called OptionsActivity, because in my project this Activity is going to display the different options my user can set to control my app. There are two list item types, one list item type just has a TextView and the second list item type just has a Button. You can put any widgets you like inside each list item type, but I kept this example simple.
The getItemView() method checks to see which list items should be type 1 or type 2. According to my static ints I defined up top, the first 5 list items will be list item type 1, and the last 5 list items will be list item type 2. So if you compile and run this, you will have a ListView that has five items that just contain a Button, and then five items that just contain a TextView.
Below is the Activity code, the activity xml file, and an xml file for each list item type.
OptionsActivity.java:
public class OptionsActivity extends ListActivity {
private static final int LIST_ITEM_TYPE_1 = 0;
private static final int LIST_ITEM_TYPE_2 = 1;
private static final int LIST_ITEM_TYPE_COUNT = 2;
private static final int LIST_ITEM_COUNT = 10;
// The first five list items will be list item type 1
// and the last five will be list item type 2
private static final int LIST_ITEM_TYPE_1_COUNT = 5;
private MyCustomAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new MyCustomAdapter();
for (int i = 0; i < LIST_ITEM_COUNT; i++) {
if (i < LIST_ITEM_TYPE_1_COUNT)
mAdapter.addItem("item type 1");
else
mAdapter.addItem("item type 2");
}
setListAdapter(mAdapter);
}
private class MyCustomAdapter extends BaseAdapter {
private ArrayList<String> mData = new ArrayList<String>();
private LayoutInflater mInflater;
public MyCustomAdapter() {
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final String item) {
mData.add(item);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
if(position < LIST_ITEM_TYPE_1_COUNT)
return LIST_ITEM_TYPE_1;
else
return LIST_ITEM_TYPE_2;
}
#Override
public int getViewTypeCount() {
return LIST_ITEM_TYPE_COUNT;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public String getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch(type) {
case LIST_ITEM_TYPE_1:
convertView = mInflater.inflate(R.layout.list_item_type1, null);
holder.textView = (TextView)convertView.findViewById(R.id.list_item_type1_text_view);
break;
case LIST_ITEM_TYPE_2:
convertView = mInflater.inflate(R.layout.list_item_type2, null);
holder.textView = (TextView)convertView.findViewById(R.id.list_item_type2_button);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
}
activity_options.xml:
<LinearLayout 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"
android:orientation="vertical"
>
<ListView
android:id="#+id/optionsList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
list_item_type_1.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_item_type1_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/list_item_type1_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text goes here" />
</LinearLayout>
list_item_type2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_item_type2_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/list_item_type2_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button text goes here" />
</LinearLayout>
This code is easy to understand.
three_horizontal_text_views_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/leftTextView"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/centreTextView"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/rightTextView"/>
</LinearLayout>
ThreeStrings.java
public class ThreeStrings {
private String left;
private String right;
private String centre;
public ThreeStrings(String left, String right, String centre) {
this.left = left;
this.right = right;
this.centre = centre;
}
}
ThreeHorizontalTextViewsAdapter.java
public class ThreeHorizontalTextViewsAdapter extends ArrayAdapter<ThreeStrings> {
private int layoutResource;
public ThreeHorizontalTextViewsAdapter(Context context, int layoutResource, List<ThreeStrings> threeStringsList) {
super(context, layoutResource, threeStringsList);
this.layoutResource = layoutResource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
view = layoutInflater.inflate(layoutResource, null);
}
ThreeStrings threeStrings = getItem(position);
if (threeStrings != null) {
TextView leftTextView = (TextView) view.findViewById(R.id.leftTextView);
TextView rightTextView = (TextView) view.findViewById(R.id.rightTextView);
TextView centreTextView = (TextView) view.findViewById(R.id.centreTextView);
if (leftTextView != null) {
leftTextView.setText(threeStrings.getLeft());
}
if (rightTextView != null) {
rightTextView.setText(threeStrings.getRight());
}
if (centreTextView != null) {
centreTextView.setText(threeStrings.getCentre());
}
}
return view;
}
}
main_layout.xml
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.androidapplication.ListActivity">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"></ListView>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<ThreeStrings> threeStringsList = new ArrayList<>();
ThreeStrings threeStrings = new ThreeStrings("a", "b", "c");
threeStringsList.add(threeStrings);
ListView listView = (ListView)findViewById(R.id.listView);
ThreeHorizontalTextViewsAdapter threeHorizontalTextViewsAdapter = new ThreeHorizontalTextViewsAdapter(this, R.layout.three_horizontal_text_views_layout, threeStringsList);
listView.setAdapter(threeHorizontalTextViewsAdapter);
}
//......}
Google has an example called EfficientAdapter, which in my opinion is the best simple example of how to implement custom adapters. http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/List14.html
#CommonsWare has written a good explanation of the patterns used in the above example
http://commonsware.com/Android/excerpt.pdf
check this link, in very simple via the convertView, we can get the layout of a row which will be displayed in listview (which is the parentView).
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.itemlistrow, null);
}
using the position, you can get the objects of the List<Item>.
Item p = items.get(position);
after that we'll have to set the desired details of the object to the identified form widgets.
if (p != null) {
TextView tt = (TextView) v.findViewById(R.id.id);
TextView tt1 = (TextView) v.findViewById(R.id.categoryId);
TextView tt3 = (TextView) v.findViewById(R.id.description);
if (tt != null) {
tt.setText(p.getId());
}
if (tt1 != null) {
tt1.setText(p.getCategory().getId());
}
if (tt3 != null) {
tt3.setText(p.getDescription());
}
}
then it will return the constructed view which will be attached to the parentView (which is a ListView/GridView).
Data Model
public class DataModel {
String name;
String type;
String version_number;
String feature;
public DataModel(String name, String type, String version_number, String feature ) {
this.name=name;
this.type=type;
this.version_number=version_number;
this.feature=feature;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getVersion_number() {
return version_number;
}
public String getFeature() {
return feature;
}
}
Array Adapter
public class CustomAdapter extends ArrayAdapter<DataModel> implements View.OnClickListener{
private ArrayList<DataModel> dataSet;
Context mContext;
// View lookup cache
private static class ViewHolder {
TextView txtName;
TextView txtType;
TextView txtVersion;
ImageView info;
}
public CustomAdapter(ArrayList<DataModel> data, Context context) {
super(context, R.layout.row_item, data);
this.dataSet = data;
this.mContext=context;
}
#Override
public void onClick(View v) {
int position=(Integer) v.getTag();
Object object= getItem(position);
DataModel dataModel=(DataModel)object;
switch (v.getId())
{
case R.id.item_info:
Snackbar.make(v, "Release date " +dataModel.getFeature(), Snackbar.LENGTH_LONG)
.setAction("No action", null).show();
break;
}
}
private int lastPosition = -1;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
DataModel dataModel = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_item, parent, false);
viewHolder.txtName = (TextView) convertView.findViewById(R.id.name);
viewHolder.txtType = (TextView) convertView.findViewById(R.id.type);
viewHolder.txtVersion = (TextView) convertView.findViewById(R.id.version_number);
viewHolder.info = (ImageView) convertView.findViewById(R.id.item_info);
result=convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result=convertView;
}
Animation animation = AnimationUtils.loadAnimation(mContext, (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
result.startAnimation(animation);
lastPosition = position;
viewHolder.txtName.setText(dataModel.getName());
viewHolder.txtType.setText(dataModel.getType());
viewHolder.txtVersion.setText(dataModel.getVersion_number());
viewHolder.info.setOnClickListener(this);
viewHolder.info.setTag(position);
// Return the completed view to render on screen
return convertView;
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
ArrayList<DataModel> dataModels;
ListView listView;
private static CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView=(ListView)findViewById(R.id.list);
dataModels= new ArrayList<>();
dataModels.add(new DataModel("Apple Pie", "Android 1.0", "1","September 23, 2008"));
dataModels.add(new DataModel("Banana Bread", "Android 1.1", "2","February 9, 2009"));
dataModels.add(new DataModel("Cupcake", "Android 1.5", "3","April 27, 2009"));
dataModels.add(new DataModel("Donut","Android 1.6","4","September 15, 2009"));
dataModels.add(new DataModel("Eclair", "Android 2.0", "5","October 26, 2009"));
dataModels.add(new DataModel("Froyo", "Android 2.2", "8","May 20, 2010"));
dataModels.add(new DataModel("Gingerbread", "Android 2.3", "9","December 6, 2010"));
dataModels.add(new DataModel("Honeycomb","Android 3.0","11","February 22, 2011"));
dataModels.add(new DataModel("Ice Cream Sandwich", "Android 4.0", "14","October 18, 2011"));
dataModels.add(new DataModel("Jelly Bean", "Android 4.2", "16","July 9, 2012"));
dataModels.add(new DataModel("Kitkat", "Android 4.4", "19","October 31, 2013"));
dataModels.add(new DataModel("Lollipop","Android 5.0","21","November 12, 2014"));
dataModels.add(new DataModel("Marshmallow", "Android 6.0", "23","October 5, 2015"));
adapter= new CustomAdapter(dataModels,getApplicationContext());
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DataModel dataModel= dataModels.get(position);
Snackbar.make(view, dataModel.getName()+"\n"+dataModel.getType()+" API: "+dataModel.getVersion_number(), Snackbar.LENGTH_LONG)
.setAction("No action", null).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
row_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Marshmallow"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#android:color/black" />
<TextView
android:id="#+id/type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/name"
android:layout_marginTop="5dp"
android:text="Android 6.0"
android:textColor="#android:color/black" />
<ImageView
android:id="#+id/item_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#android:drawable/ic_dialog_info" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<TextView
android:id="#+id/version_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="API: "
android:textColor="#android:color/black"
android:textStyle="bold" />
<TextView
android:id="#+id/version_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="23"
android:textAppearance="?android:attr/textAppearanceButton"
android:textColor="#android:color/black"
android:textStyle="bold" />
</LinearLayout>
</RelativeLayout>
You can take a look at this sample in the official ApiDemos. It shows how to extend BaseAdapter and apply it to a ListView. After that, just look at the reference for BaseAdapter and try to understand what each method does (including the inherited ones) and when/how to use it.
Also, Google is your friend :).
Here is the complete walk through to create a custom adapter for list view step by step -
https://www.caveofprogramming.com/guest-posts/custom-listview-with-imageview-and-textview-in-android.html
public class CustomAdapter extends BaseAdapter{
String [] result;
Context context;
int [] imageId;
private static LayoutInflater inflater=null;
public CustomAdapter(MainActivity mainActivity, String[] prgmNameList, int[] prgmImages) {
// TODO Auto-generated constructor stub
result=prgmNameList;
context=mainActivity;
imageId=prgmImages;
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return result.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public class Holder
{
TextView tv;
ImageView img;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.program_list, null);
holder.tv=(TextView) rowView.findViewById(R.id.textView1);
holder.img=(ImageView) rowView.findViewById(R.id.imageView1);
holder.tv.setText(result[position]);
holder.img.setImageResource(imageId[position]);
rowView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(context, "You Clicked "+result[position], Toast.LENGTH_LONG).show();
}
});
return rowView;
}
}
A more compact example of a custom adapter (using list array as my data):
class MyAdapter extends ArrayAdapter<Object> {
public ArrayAdapter(Context context, List<MyObject> objectList) {
super(context, R.layout.my_list_item, R.id.textViewTitle, objectList.toArray());
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
TextView title = (TextView) row.findViewById(R.id.textViewTitle);
ImageView icon = (ImageView) row.findViewById(R.id.imageViewAccessory);
MyObject obj = (MyObject) getItem(position);
icon.setImageBitmap( ... );
title.setText(obj.name);
return row;
}
}
And this is how to use it:
List<MyObject> objectList = ...
MyAdapter adapter = new MyAdapter(this.getActivity(), objectList);
listView.setAdapter(adapter);
BaseAdapter is best custom adapter for listview.
Class MyAdapter extends BaseAdapter{}
and it has many functions such as getCount(), getView() etc.
It is very simple.
import android.content.Context;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
/**
* Created by Belal on 9/14/2017.
*/
//we need to extend the ArrayAdapter class as we are building an adapter
public class MyListAdapter extends ArrayAdapter<Hero> {
//the list values in the List of type hero
List<Hero> heroList;
//activity context
Context context;
//the layout resource file for the list items
int resource;
//constructor initializing the values
public MyListAdapter(Context context, int resource, List<Hero> heroList) {
super(context, resource, heroList);
this.context = context;
this.resource = resource;
this.heroList = heroList;
}
//this will return the ListView Item as a View
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//we need to get the view of the xml for our list item
//And for this we need a layoutinflater
LayoutInflater layoutInflater = LayoutInflater.from(context);
//getting the view
View view = layoutInflater.inflate(resource, null, false);
//getting the view elements of the list from the view
ImageView imageView = view.findViewById(R.id.imageView);
TextView textViewName = view.findViewById(R.id.textViewName);
TextView textViewTeam = view.findViewById(R.id.textViewTeam);
Button buttonDelete = view.findViewById(R.id.buttonDelete);
//getting the hero of the specified position
Hero hero = heroList.get(position);
//adding values to the list item
imageView.setImageDrawable(context.getResources().getDrawable(hero.getImage()));
textViewName.setText(hero.getName());
textViewTeam.setText(hero.getTeam());
//adding a click listener to the button to remove item from the list
buttonDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//we will call this method to remove the selected value from the list
//we are passing the position which is to be removed in the method
removeHero(position);
}
});
//finally returning the view
return view;
}
//this method will remove the item from the list
private void removeHero(final int position) {
//Creating an alert dialog to confirm the deletion
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Are you sure you want to delete this?");
//if the response is positive in the alert
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//removing the item
heroList.remove(position);
//reloading the list
notifyDataSetChanged();
}
});
//if response is negative nothing is being done
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
//creating and displaying the alert dialog
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}
Source: Custom ListView Android Tutorial
public class CustomAdapter extends BaseAdapter{
ArrayList<BookPojo> data;
Context ctx;
int index=0;
public CustomAdapter(ArrayList<BookPojo> data, Context ctx) {
super();
this.data = data;
this.ctx = ctx;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertview, ViewGroup parent) {
// TODO Auto-generated method stub
View v=convertview;
if(v==null){
LayoutInflater vi=LayoutInflater.from(ctx);
v=vi.inflate(R.layout.messgeview,null);
}
RelativeLayout rlmessage=(RelativeLayout)v.findViewById(R.id.rlmessgeview);
TextView tvisdn=(TextView)v.findViewById(R.id.tvisdn);
TextView tvtitle=(TextView)v.findViewById(R.id.tvtitle);
TextView tvauthor=(TextView)v.findViewById(R.id.tvauthor);
TextView tvprice=(TextView)v.findViewById(R.id.tvprice);
BookPojo bpj=data.get(position);
tvisdn.setText(bpj.isdn+"");
tvtitle.setText(bpj.title);
tvauthor.setText(bpj.author);
tvprice.setText(bpj.price+"");
if(index%2==0)
{
rlmessage.setBackgroundColor(Color.BLUE);
}
else
{
rlmessage.setBackgroundColor(Color.YELLOW);
}
index++;
return v;
}
}
import android.app.Activity;
import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import org.json.JSONObject;
import java.util.ArrayList;
public class OurteamAdapter extends BaseAdapter {
Context cont;
ArrayList<OurteamModel> llist;
OurteamAdapter madap;
LayoutInflater inflater;
JsonHelper Jobj;
String Id;
JSONObject obj = null;
int position = 0;
public OurteamAdapter(Context c,ArrayList<OurteamModel> Mi)
{
this.cont = c;
this.llist = Mi;
}
#Override
public int getCount()
{
// TODO Auto-generated method stub
return llist.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return llist.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
// TODO Auto-generated method stub
if(convertView == null)
{
LayoutInflater in = (LayoutInflater) cont.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = in.inflate(R.layout.doctorlist, null);
}
TextView category = (TextView) convertView.findViewById(R.id.button1);
TextView title = (TextView) convertView.findViewById(R.id.button2);
ImageView i1=(ImageView) convertView.findViewById(R.id.imageView1);
category.setText(Html.fromHtml(llist.get(position).getGalleryName()));
title.setText(Html.fromHtml(llist.get(position).getGalleryDetail()));
if(llist.get(position).getImagesrc()!=null)
{
i1.setImageBitmap(llist.get(position).getImagesrc());
}
else
{
i1.setImageResource(R.drawable.anandlogo);
}
return convertView;
}
}
I have stored some value in arraylist if checkbox is clicked but i am having a difficult time to get it from listView class. How can i get it. Also if I keep
clickListener in view that contains checkbox and textView, the checkbox click is not working but if i click in textview it works. How to fix it. Below is my code.
Thanks in advance
singlerow_compare.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:id="#+id/singleRow" android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textViewCompare" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageViewCompare"/>
</RelativeLayout>
listview xml:
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listViewCompare" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Compare"
android:id="#+id/compare"
android:layout_alignParentBottom="true"/>
ListView.java
listView = (HorizontalListView) findViewById(R.id.listViewCompare);
compareBtn = (Button) findViewById(R.id.compare);
listView.setAdapter(new CustomAdapter(this, nameList, imageList));
compareBtn.setOnClickListener(new View.OnClickListener()
{ #Override
public void onClick(View view) {
//I need to have addCheckBoxValue arraylist from adapter here
}
}
CustomAdapter.java
public class CustomAdapter extends BaseAdapter {
ArrayList result;
Context context;
Drawable [] imageId;
protected ArrayList<String> addCheckBoxValue;
private static LayoutInflater inflater=null;
public CustomAdapter(CompareListView mainActivity, ArrayList nameList, Drawable[] imageList) {
result=nameList;
context=mainActivity;
imageId=imageList;
inflater = ( LayoutInflater )context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public class Holder
{
TextView tv;
ImageView img;
CheckBox checkBox;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup) {
addCheckBoxValue = new ArrayList();
final Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.singlerow_compare, null);
holder.tv=(TextView) rowView.findViewById(R.id.textViewCompare);
holder.checkBox = (CheckBox) rowView.findViewById(R.id.imageViewCompare);
holder.tv.setText(result.get(i).toString());
holder.checkBox.setButtonDrawable(imageId[i]);
final String selectedCbValue = holder.tv.getText().toString();
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
boolean checked = ((CheckBox) view).isChecked();
if(checked){
if (!addCheckBoxValue.contains(selectedCbValue))
addCheckBoxValue.add(selectedCbValue);
}else{
if (addCheckBoxValue.contains(selectedCbValue))
addCheckBoxValue.remove(selectedCbValue);
}
}
});
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//if i click on textView, it works but when i click on checkbox here, it doesnt work why?? So i have clicklistener in checkbox abov
}
});
return rowView;
}
Create Following method in your CustomAdapter class:
public ArrayList<String> getCheckBoxValue(){
return addCheckBoxValue;
}
And in your ListActivity. Change your activity code like this:
private CustomAdapter listAdapter; // declare this before on create
Now where you are setting adapter in your on create write this code:
listAdapter = new CustomAdapter(this, nameList, imageList)
// set Adapter like this:
listView.setAdapter(listAdapter);
your button on click code should be like this:
compareBtn.setOnClickListener(new View.OnClickListener()
{ #Override
public void onClick(View view) {
//I need to have addCheckBoxValue arraylist from adapter here
listAdapter.getCheckBoxValue(); // do whatever you want to do here
}
}
Happy Coding!!!
I suggest you make boolean array for checkbox and maintain it like this way,this worked for me
public class CustomAdapter extends BaseAdapter {
private final LayoutInflater inflater;
private final Context context;
private List<ModelPooja> listData;
public CustomAdapter(Context mainActivity, List<ModelPooja> listData) {
context = mainActivity;
this.listData = listData;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_item_poojaselection, null);
holder.tv = (TextView) convertView.findViewById(R.id.list_item_poojaname);
holder.checks = (CheckBox) convertView.findViewById(R.id.list_item_poojacheck);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.checks.setOnCheckedChangeListener(null);
holder.checks.setFocusable(false);
if (listData.get(position).isselected) {
holder.checks.setChecked(true);
} else {
holder.checks.setChecked(false);
}
holder.checks.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton cb, boolean b) {
if (checkMaxLimit()) {
if (listData.get(position).isselected && b) {
holder.checks.setChecked(false);
listData.get(position).isselected = false;
} else {
holder.checks.setChecked(false);
listData.get(position).isselected = false;
Toast.makeText(context, "Max limit reached", Toast.LENGTH_SHORT).show();
}
} else {
if (b) {
listData.get(position).isselected = true;
} else {
listData.get(position).isselected = false;
}
}
}
});
holder.tv.setText(listData.get(position).getPOOJA_LISTING_NAME());
return convertView;
}
public boolean checkMaxLimit() {
int countermax = 0;
for(ModelPooja item : listData){
if(item.isselected){
countermax++;
}
}
return countermax >= 5;
}
public class ViewHolder {
TextView tv;
public CheckBox checks;
}
}
I have a row which is represented by an image, some text and a CheckBoxes. Whenever I'm trying to use the OnItemClickListener for the rows, the event won't fire up when clicking the CheckBoxes.
I also tried checkbox.onCheckedChangedListener but it gives me Null Pointer at findViewByID. I checked, the ID I am looking for is alright, no typos in there.
I'd like to make usage of this OnItemClickListener so later on I can play with the checkboxes. Any ideas?
Code:
ADAPTER:
public class FilterAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> mFilters;
private ArrayList<Integer> mPictures;
private Typeface Bebas, DroidSans;
public FilterAdapter(Context context, ArrayList<String> filters, ArrayList<Integer> pictures) {
this.mContext = context;
this.mFilters = filters;
this.mPictures = pictures;
}
#Override
public int getCount() {
return mFilters.size();
}
#Override
public Object getItem(int position) {
return mFilters.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.category_filter_item, null);
}
DroidSans = Typeface.createFromAsset(mContext.getAssets(), "fonts/DroidSans.ttf");
ImageView filter_img = (ImageView) convertView.findViewById(R.id.category_picture);
TextView filter_category = (TextView) convertView.findViewById(R.id.filter_category);
CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.check_box);
filter_category.setTypeface(DroidSans);
filter_category.setText(mFilters.get(position));
filter_img.setBackgroundResource(mPictures.get(position));
return convertView;
}
}
Class where using the Adapter:
public class CheckinFilters extends Fragment {
private ListView mListView;
private FilterAdapter filterAdapter;
private ArrayList<String> l = new ArrayList<String>();
private ArrayList<Integer> drawables = new ArrayList<Integer>();
private Typeface Bebas;
private ArrayList<Integer> checkboxes = new ArrayList<Integer>();
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor editor;
public CheckinFilters() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_checkin_filters, container, false);
l.add("Chill");
l.add("Eat");
l.add("Explore");
l.add("Move");
l.add("Party");
l.add("Whatever");
drawables.add(R.drawable.category_chill);
drawables.add(R.drawable.category_eat);
drawables.add(R.drawable.category_explore);
drawables.add(R.drawable.category_move);
drawables.add(R.drawable.category_party);
drawables.add(R.drawable.category_whatever);
mListView = (ListView) view.findViewById(R.id.filter_list);
filterAdapter = new FilterAdapter(view.getContext(), l, drawables);
mListView.setAdapter(filterAdapter);
sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
Bebas = Typeface.createFromAsset(view.getContext().getAssets(), "fonts/BebasNeue.otf");
TextView mainHeader = (TextView) view.findViewById(R.id.filters_text);
mainHeader.setTypeface(Bebas);
SearchView filter_categories = (SearchView) view.findViewById(R.id.filter_categories);
int searchImgID = getResources().getIdentifier("android:id/search_button", null, null);
ImageView searchViewHint = (ImageView) filter_categories.findViewById(searchImgID);
searchViewHint.setImageResource(R.drawable.ab_icon_search);
int searchPlateID = filter_categories.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
View searchPlateView = filter_categories.findViewById(searchPlateID);
if (searchPlateView != null) {
searchPlateView.setBackgroundResource(R.drawable.search_location_shape);
}
int searchViewID = filter_categories.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
TextView textView = (TextView) filter_categories.findViewById(searchViewID);
textView.setTextColor(Color.GRAY);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.check_box);
return view;
}
private void save() {
sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
editor = sharedPreferences.edit();
editor.putInt("first", checkboxes.size());
for (int i = 0; i < checkboxes.size(); i++) {
editor.remove("Status_" + i);
editor.putInt("Status_" + i, checkboxes.get(i));
}
editor.commit();
}
private void load() {
sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
int size = sharedPreferences.getInt("first", 0);
for (int i = 0; i < size; i++) {
checkboxes.add(sharedPreferences.getInt("Status_" + i, 0));
}
}
#Override
public void onPause() {
super.onPause();
save();
}
#Override
public void onResume() {
super.onResume();
load();
}
}
Layout I'm inflating for Adapter:
<?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">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ECF0F1">
<ImageView
android:id="#+id/category_picture"
android:layout_width="70dp"
android:layout_height="60dp"
android:background="#drawable/sm_profile"/>
<TextView
android:id="#+id/filter_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/category_picture"
android:padding="10dp"
android:text="Party"
android:textColor="#color/enloop_dark_gray"
android:textSize="18dp"/>
<CheckBox
android:id="#+id/check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="10dp"/>
</RelativeLayout>
</RelativeLayout>
Instead of using OnItemClickListener in CheckinFilters.java, you should add that code in getView() method of FilterAdapter. You are actually adding checkbox for every row but the id for all checkbox is same, so you can't apply customized code for every checkbox.
To be able to make use of all checkboxes you can put checkbox code in getView() method because it also contains an argument called position. So you can just get the position and apply OnItemClickListener to every single checkbox. That way it will work.
public class FilterAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> mFilters;
private ArrayList<Integer> mPictures;
private Typeface Bebas, DroidSans;
public FilterAdapter(Context context, ArrayList<String> filters, ArrayList<Integer> pictures) {
this.mContext = context;
this.mFilters = filters;
this.mPictures = pictures;
}
#Override
public int getCount() {
return mFilters.size();
}
#Override
public Object getItem(int position) {
return mFilters.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.category_filter_item, null);
}
DroidSans = Typeface.createFromAsset(mContext.getAssets(), "fonts/DroidSans.ttf");
ImageView filter_img = (ImageView) convertView.findViewById(R.id.category_picture);
TextView filter_category = (TextView) convertView.findViewById(R.id.filter_category);
CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.check_box);
filter_category.setTypeface(DroidSans);
filter_category.setText(mFilters.get(position));
filter_img.setBackgroundResource(mPictures.get(position));
if(position == 0) {
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked)
else {
}
}
});
}
//Similarly add OnClickListener to other checkboxes.
return convertView;
}
}
I'm trying to make a task manager, and I only have one problem. I have a listview that gets inflated. All the elements in the listview are correct. The problem is that when I select an item, the listview will select another item away. I've heard listviews repopulate the list as it scrolls down to save memory. I think this may be some sort of problem. Here is a picture of the problem.
If i had more apps loaded, then it would continue to select multiple at once.
Here is the code of my adapter and activity and XML associated
public class TaskAdapter extends BaseAdapter{
private Context mContext;
private List<TaskInfo> mListAppInfo;
private PackageManager mPack;
public TaskAdapter(Context c, List<TaskInfo> list, PackageManager pack) {
mContext = c;
mListAppInfo = list;
mPack = pack;
}
#Override
public int getCount() {
return mListAppInfo.size();
}
#Override
public Object getItem(int position) {
return mListAppInfo.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
TaskInfo entry = mListAppInfo.get(position);
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.from(mContext);
//System.out.println("Setting LayoutInflater in TaskAdapter " +mContext +" " +R.layout.taskinfo +" " +R.id.tmbox);
convertView = inflater.inflate(R.layout.taskinfo,null);
}
ImageView ivIcon = (ImageView)convertView.findViewById(R.id.tmImage);
ivIcon.setImageDrawable(entry.getIcon());
TextView tvName = (TextView)convertView.findViewById(R.id.tmbox);
tvName.setText(entry.getName());
convertView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
final CheckBox checkBox = (CheckBox)v.findViewById(R.id.tmbox);
if(v.isSelected())
{
System.out.println("Listview not selected ");
//CK.get(arg2).setChecked(false);
checkBox.setChecked(false);
v.setSelected(false);
}
else
{
System.out.println("Listview selected ");
//CK.get(arg2).setChecked(true);
checkBox.setChecked(true);
v.setSelected(true);
}
}
});
return convertView;
public class TaskManager extends Activity implements Runnable
{
private ProgressDialog pd;
private TextView ram;
private String s;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.taskpage);
setTitleColor(Color.YELLOW);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run()
{
//System.out.println("In Taskmanager Run() Thread");
final PackageManager pm = getPackageManager();
final ListView box = (ListView) findViewById(R.id.cBoxSpace);
final List<TaskInfo> CK = populate(box, pm);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
ram.setText(s);
box.setAdapter(new TaskAdapter(TaskManager.this, CK, pm));
//System.out.println("In Taskmanager runnable Run()");
endChecked(CK);
}
});
handler.sendEmptyMessage(0);
}
Taskinfo.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal">
<ImageView
android:id="#+id/tmImage"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="centerCrop"
android:adjustViewBounds="false"
android:focusable="false" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tmbox"
android:lines="2"/>
</LinearLayout>
Taskpage.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="#+id/cBoxSpace"
android:layout_width="wrap_content"
android:layout_height="400dp"
android:orientation="vertical"/>
<TextView
android:id="#+id/RAM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp" />
<Button
android:id="#+id/endButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="End Selected Tasks" />
</LinearLayout>
Any ideas for what reason mutliple items are selected with a single click would be GREATLY appreciated. I've been messing around with different implementations and listeners and listadapters but to no avail.
I think the point is you only save checking state in the view(v.setSelected).
And you reuse these view, so its checkbox is always not change its state.
You can create a state array to save every checking state of every TaskInfo, and check this array when you create a view.
for example
// default is false
ArrayList<Boolean> checkingStates = new ArrayList<Boolean>(mListAppInfo.size());
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
TaskInfo entry = mListAppInfo.get(position);
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(R.layout.taskinfo,null);
}
ImageView ivIcon = (ImageView)convertView.findViewById(R.id.tmImage);
ivIcon.setImageDrawable(entry.getIcon());
TextView tvName = (TextView)convertView.findViewById(R.id.tmbox);
tvName.setText(entry.getName());
final CheckBox checkBox = (CheckBox)v.findViewById(R.id.tmbox);
checkBox.setChecked(checkingStates.get(position));
convertView.setSelected(checkingStates.get(position));
convertView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
if(v.isSelected())
{
System.out.println("Listview not selected ");
//CK.get(arg2).setChecked(false);
checkBox.setChecked(false);
v.setSelected(false);
checkingStates.get(position) = false;
}
else
{
System.out.println("Listview selected ");
//CK.get(arg2).setChecked(true);
checkBox.setChecked(true);
v.setSelected(true);
checkingStates.get(position) = true;
}
}
});
return convertView;
}
I'm not 100% sure what you are trying to do, but part of your problem might be related to the condition in your onClick method:
if(v.isSelected())
I think you want that to read
if(v.isChecked())
isSelected is inherited from View, and it means something different from isChecked
Also, the whether the CheckBox is checked or not is independent from your data model since it is a recycled view. Your CheckBox should be checked based on entry (I'm assuming your TextInfo class has an isChecked() method that returns a boolean:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
TaskInfo entry = mListAppInfo.get(position);
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.from(mContext);
//System.out.println("Setting LayoutInflater in TaskAdapter " +mContext +" " +R.layout.taskinfo +" " +R.id.tmbox);
convertView = inflater.inflate(R.layout.taskinfo,null);
}
ImageView ivIcon = (ImageView)convertView.findViewById(R.id.tmImage);
ivIcon.setImageDrawable(entry.getIcon());
TextView tvName = (TextView)convertView.findViewById(R.id.tmbox);
tvName.setText(entry.getName());
CheckBox checkBox = (CheckBox)v.findViewById(R.id.tmbox);
checkBox.setChecked(entry.isChecked());
}
I don't think you need the View.OnClickListener you are attaching to convertView. You should handle that in the OnItemClickListener attached to the ListView. Assuming your ListView is called listView and TaskInfo instances have setChecked and isChecked methods:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
entry = mListAppInfo.get(position);
entry.setChecked(!entry.isChecked());
}
});
First of all don't set the list checked or unchecked on view position.
because view position means only visible items position in your listview but you would like to set checked or uncheked status on a particular list item.
That's why this problem arises in your code.
You have the need to set the items checked and unchecked on your custom arraylist getter setter like the code i have attached below:
package com.app.adapter;
public class CategoryDynamicAdapter {
public static ArrayList<CategoryBean> categoryList = new ArrayList<CategoryBean>();
Context context;
Typeface typeface;
public static String videoUrl = "" ;
Handler handler;
Runnable runnable;
// constructor
public CategoryDynamicAdapter(Activity a, Context context, Bitmap [] imagelist,ArrayList<CategoryBean> list) {
this.context = context;
this.categoryList = list;
this.a = a;
}
// Baseadapter to the set the data response from web service into listview.
public BaseAdapter mEventAdapter = new BaseAdapter() {
#Override
public int getCount() {
return categoryList.size();
}
#Override
public Object getItem(int position) {
return categoryList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
class ViewHolder {
TextView title,category,uploadedBy;
ImageView image;
RatingBar video_rating;
Button report_video ,Flag_video;
}
public View getView(final int position, View convertView, final ViewGroup parent) {
ViewHolder vh = null ;
if(convertView == null) {
vh = new ViewHolder();
convertView = LayoutInflater.from(context).inflate (R .layout.custom_category_list_layout,null,false);
vh.title = (TextView) convertView .findViewById (R.id.title);
vh.image = (ImageView) convertView.findViewById(R.id.Imagefield);
convertView.setTag(vh);
}
else
{
vh=(ViewHolder) convertView.getTag();
}
try
{
final CategoryBean Cb = categoryList.get(position);
//pay attention to code below this line i have shown here how to select a listview using arraylist getter setter objects
String checkedStatus = Cb.getCheckedStringStaus();
if(checkdStatus.equal("0")
{
System.out.println("Listview not selected ");
//CK.get(arg2).setChecked(false);
checkBox.setChecked(false);
v.setSelected(false);
}
else ////checkdStatus.equal("1")
{
System.out.println("Listview selected ");
//CK.get(arg2).setChecked(true);
checkBox.setChecked(true);
v.setSelected(true);
}
catch (Exception e)
{
e.printStackTrace();
}