I create a adapter :
public class Adapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<RowBean> data = null;
private LayoutInflater inflater;
private ValueFilter valueFilter;
private ArrayList<RowBean> mStringFilterList;
public Adapter(Context context, ArrayList<RowBean> data) {
super();
this.context = context;
this.data = data;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mStringFilterList = data;
getFilter();
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RowBeanHolder holder;
RowBean rowBean = data.get(position);
if(convertView == null){
holder = new RowBeanHolder();
convertView = inflater.inflate(R.layout.all_object_holder,null);
holder.txtTitle = (TextView) convertView.findViewById(R.id.showText);
holder.selected = (CheckBox) convertView.findViewById(R.id.checkBox12);
}else{
holder = (RowBeanHolder) convertView.getTag();
}
if(rowBean != null) {
holder.txtTitle.setText(rowBean.getTitle());
holder.selected.setChecked(rowBean.isSelected());
}
return convertView;
}
#Override
public Filter getFilter() {
if(valueFilter==null) {
valueFilter=new ValueFilter();
}
return valueFilter;
}
private class RowBeanHolder {
TextView txtTitle;
CheckBox selected;
}
private class ValueFilter extends Filter {
//Invoked in a worker thread to filter the data according to the constraint.
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if(constraint!=null && constraint.length()>0){
ArrayList<RowBean> filterList=new ArrayList<>();
for(int i=0;i<mStringFilterList.size();i++){
if((mStringFilterList.get(i).getTitle().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
RowBean contacts = new RowBean();
contacts.setTitle(mStringFilterList.get(i).getTitle());
contacts.setSelected(mStringFilterList.get(i).isSelected());
filterList.add(contacts);
}
}
results.count=filterList.size();
results.values=filterList;
}else{
results.count=mStringFilterList.size();
results.values=mStringFilterList;
}
return results;
}
//Invoked in the UI thread to publish the filtering results in the user interface.
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
data=(ArrayList<RowBean>) results.values;
notifyDataSetChanged();
}
}
}
When I start my activity with this adapter I log I see this :
Process: com.maps, PID: 20174
java.lang.NullPointerException: Attempt to read from field 'android.widget.TextView com.maps.Adapter.Adapter$RowBeanHolder.txtTitle' on a null object reference
this is a line :
holder.txtTitle.setText(rowBean.getTitle());
This is a layout all_object_holder:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="#+id/checkBox12"
android:layout_width="50dp"
android:layout_height="50dp"
android:clickable="false"
android:button="#xml/setting_checkbox"
android:focusable="false"
android:gravity="center" />
<TextView
android:id="#+id/showText"
android:layout_width="395dp"
android:layout_height="wrap_content"
android:text="#string/show_choose_point"
android:textColor="#000000"
android:layout_alignBaseline="#+id/checkBox12"
android:layout_alignBottom="#+id/checkBox12"
android:layout_toRightOf="#+id/checkBox12"
android:layout_toEndOf="#+id/checkBox12" />
</RelativeLayout>
Add line
convertView.setTag(holder);
without it convertView.getTag() will return null.
if(convertView == null){
holder = new RowBeanHolder();
convertView = inflater.inflate(R.layout.all_object_holder,null);
holder.txtTitle = (TextView) convertView.findViewById(R.id.showText);
holder.selected = (CheckBox)
convertView.setTag(holder);
}
You didn't add convertView.setTag(holder). Please add it to your code and check.
NullPointerException occurs because your holder object is null sometimes. You should setTag of your convertView, just add convertView.setTag(holder); method to getView method like that:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RowBeanHolder holder;
RowBean rowBean = data.get(position);
if(convertView == null){
holder = new RowBeanHolder();
convertView = inflater.inflate(R.layout.all_object_holder,null);
holder.txtTitle = (TextView) convertView.findViewById(R.id.showText);
holder.selected = (CheckBox) convertView.findViewById(R.id.checkBox12);
convertView.setTag(holder);
}else{
holder = (RowBeanHolder) convertView.getTag();
}
if(rowBean != null) {
holder.txtTitle.setText(rowBean.getTitle());
holder.selected.setChecked(rowBean.isSelected());
}
return convertView;
}
Good luck.
Update your code with this code
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RowBeanHolder holder = new RowBeanHolder();
RowBean rowBean = data.get(position);
if(convertView == null){
convertView = inflater.inflate(R.layout.all_object_holder,null);
}
holder.txtTitle = (TextView) convertView.findViewById(R.id.showText);
holder.selected = (CheckBox) convertView.findViewById(R.id.checkBox12);
if(rowBean != null) {
holder.txtTitle.setText(rowBean.getTitle());
holder.selected.setChecked(rowBean.isSelected());
}
return convertView;
}
Related
I've been trying to implement a multi-select spinner on my own. So the problem is I'm able to select the checkboxes but when I close and open the spinner again, the selected checkboxes get deselected. So I thought I would implement my own itemclick listener to the spinner and use the positions to check the checkboxes. Now, my spinner is not dropping down.
Here's the code for the main activity.
public class MyProfileActivity extends Activity implements
View.OnClickListener, SpinnerMultiSelectAdapter.OnListItemClickListener{
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
lang_spinner_profile = findViewById(R.id.lang_spinner_profile);
ArrayList<String> options = new ArrayList<>();
options.add("English");
options.add("Japanese");
options.add("Chinese");
options.add("Korean");
lang_spinner_profile.setSelection(0);
final String[] languages = {
"Select Language", "English","Chinese","Japanese","Korean"};
for (int j = 0; j < languages.length; j++) {
StateVO stateVO= new StateVO();
stateVO.setTitle(languages[j]);
stateVO.setSelected(false);
listVOs.add(stateVO);
}
Log.d("Called","Called");
myAdapter = new SpinnerMultiSelectAdapter(MyProfileActivity.this, 0,
listVOs, this);
lang_spinner_profile.setAdapter(myAdapter);
}
#Override
public void onListItemClick(int position) {
Toast.makeText(this, "Clicked at: "+position, Toast.LENGTH_SHORT).show();
}
}
This is my custom pojo class for the spinner.
public class StateVO {
private String title;
private boolean selected;
private String selectedItem;
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;
}
}
This is the spinner custom layout.
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="text"
android:textAlignment="gravity" />
<CheckBox
android:id="#+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
And finally, this is my custom adapter.
public class SpinnerMultiSelectAdapter extends ArrayAdapter<StateVO> {
private Context mContext;
static private ArrayList<StateVO> listState;
private SpinnerMultiSelectAdapter myAdapter;
private boolean isFromView = false;
List<String> selected = new ArrayList<>();
static int i=0;
List<Integer> checked= new ArrayList<>();
View itemView;
int getPosition;
private OnListItemClickListener onListItemClickListener;
public SpinnerMultiSelectAdapter(Context context, int resource, List<StateVO> objects, OnListItemClickListener onListItemClickListener) {
super(context, resource, objects);
this.mContext = context;
this.listState = (ArrayList<StateVO>) objects;
this.myAdapter = this;
this.onListItemClickListener = onListItemClickListener;
}
#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_item, null);
itemView = convertView;
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);
selected.clear();
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
getPosition = (Integer) buttonView.getTag();
holder.mCheckBox.setSelected(true);
//notifyDataSetChanged();
}
});
return convertView;
}
private class ViewHolder implements View.OnClickListener {
private TextView mTextView;
private CheckBox mCheckBox;
public ViewHolder(){
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onListItemClickListener.onListItemClick(getPosition);
}
}
public interface OnListItemClickListener {
public void onListItemClick(int position);
}
}
Any help is appreciated. Thank you.
Your adapter has few mistakes here is how it should be;
public class SpinnerMultiSelectAdapter extends ArrayAdapter<StateVO> {
private Context mContext;
private ArrayList<StateVO> listState;
private boolean isFromView = false;
List<String> selected = new ArrayList<>();
List<Integer> checked = new ArrayList<>();
private OnListItemClickListener onListItemClickListener;
public SpinnerMultiSelectAdapter(Context context, int resource, List<StateVO> objects, OnListItemClickListener onListItemClickListener) {
super(context, resource, objects);
this.mContext = context;
this.listState = (ArrayList<StateVO>) objects;
this.onListItemClickListener = onListItemClickListener;
}
#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_item, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final String str = listState.get(position).getTitle();
holder.mTextView.setText(str);
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) {
listState.get(position).setSelected(isChecked);
}
});
return convertView;
}
private class ViewHolder implements View.OnClickListener {
private TextView mTextView;
private CheckBox mCheckBox;
public ViewHolder(View convertView) {
mTextView = (TextView) convertView
.findViewById(R.id.text);
mCheckBox = (CheckBox) convertView
.findViewById(R.id.checkbox);
convertView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
/*onListItemClickListener.onListItemClick(getPosition);*/
}
}
public interface OnListItemClickListener {
public void onListItemClick(int position);
}
}
I have an arraylist that needs to be updated using the adpater. I dont have any textviews for it. Here is my code -
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
private ArrayList<MyClass> favouriteMessageList;
private MyAdapter(Activity activity, ArrayList list) {
favouriteMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
MyClass favouriteMessage = favouriteMessageList.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.messaging_favorites_layout, null);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
public void setData(ArrayList<MyClass> data) {
favouriteMessageList = data;
notifyDataSetChanged();
}
}
The setData method will receive an arraylist and I need to populate the view with my Arraylist. I am using a viewHolder. How do I achieve this?
Try like this:
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
private ArrayList<MyClass> favouriteMessageList;
private MyAdapter(Activity activity, ArrayList list) {
favouriteMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
MyClass favouriteMessage = favouriteMessageList.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.messaging_favorites_layout, null);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//Update Your Views Here
return convertView;
}
#Override
public int getCount() {
if (favouriteMessageList != null) return favouriteMessageList.size();
return 0;
}
public void setData(ArrayList<MyClass> data) {
favouriteMessageList = data;
notifyDataSetChanged();
}
}
I am new for Android development.
I was trying to implement a custom ArrayAdapter to accept custom object in Android Studio.
I have referenced the source code from some tutorial, but my screen output was improper that the custom object only fill in the TextView which link with the textViewResourceId of ArrayAdapter , but not the custom object's properties fill in all EditText in the layout appropriately.
I tried to remove textViewResourceId parameter in the constructor of ArrayAdapter to fix the problem, but Android Studio returned error - You must supply a resource ID for a TextView
I want the properties of custom object fill in all EditText and no error message be returned, can anyone give me a hint?
Here is my layout:
row_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:id="#+id/row_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<EditText
android:id="#+id/row_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="1dp"
android:layout_gravity="center_horizontal"
android:background="#color/colorWhite"/>
<EditText
android:id="#+id/row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="1dp"
android:layout_gravity="center_horizontal"
android:background="#color/colorWhite"/>
</LinearLayout>
Here is my custom object:
Row.java
public class Row
{
public int RowNo;
public String RowText;
public Row(int no, String text)
{
this.RowNo = no;
this.RowText = text;
}
}
Here is my custom ArrayAdapter:
RowAdapter.java
public class RowAdapter extends ArrayAdapter<Row> {
private final Activity _context;
private final ArrayList<Row> rows;
static class ViewHolder
{
EditText RowNo;
EditText RowText;
}
public RowAdapter(Activity context, ArrayList<Row> rows)
{
super(context,R.layout.row_layout, R.id.row_id ,rows);
this._context = context;
this.rows = rows;
}
public View GetView(int position, View convertView, ViewGroup parent){
ViewHolder holder = null;
if(convertView == null)
{
LayoutInflater inflater = _context.getLayoutInflater();
convertView = inflater.inflate(R.layout.row_layout,parent,false);
holder = new ViewHolder();
holder.RowNo = (EditText)convertView.findViewById(R.id.row_no);
holder.RowText = (EditText)convertView.findViewById(R.id.row_text);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.RowNo.setText(rows.get(position).RowNo);
holder.RowText.setText(rows.get(position).RowText);
return convertView;
}
}
Here is my Activity class:
RowActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.row_list_page);
listView = (ListView)findViewById(R.id.list_view);
ArrayList<Row> rows = new ArrayList<Row>();
rows.add(new Row(1,"Test"));
rows.add(new Row(2,"Test"));
rows.add(new Row(3"Test"));
RowAdapter adapter = new RowAdapter(this,rows);
listView.setAdapter(adapter);
}
Here is working adapter code
public class RowAdapter extends ArrayAdapter<Row> {
private final Activity _context;
private final ArrayList<Row> rows;
public class ViewHolder
{
EditText RowNo;
EditText RowText;
}
public RowAdapter(Activity context, ArrayList<Row> rows)
{
super(context,R.layout.row_layout, R.id.row_id ,rows);
this._context = context;
this.rows = rows;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder holder = null;
if(convertView == null)
{
LayoutInflater inflater = _context.getLayoutInflater();
convertView = inflater.inflate(R.layout.row_layout,parent,false);
holder = new ViewHolder();
holder.RowNo = (EditText)convertView.findViewById(R.id.row_no);
holder.RowText = (EditText)convertView.findViewById(R.id.row_text);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.RowNo.setText(""+rows.get(position).RowNo);
holder.RowText.setText(rows.get(position).RowText);
return convertView;
}
}
Your getting exception at holder.RowNo.setText(rows.get(position).RowNo);
so replace it with
holder.RowNo.setText(""+rows.get(position).RowNo);
Change with below code:-
RowAdapter.java
public class RowAdapter extends BaseAdapter {
private final Context _context;
private final ArrayList<Row> rows;
public RowAdapter(Context context, ArrayList<Row> rows)
{
this._context = context;
this.rows = rows;
}
#Override
public int getCount() {
return rows.size();
}
#Override
public Object getItem(int position) {
return rows;
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater = (LayoutInflater) _context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView=inflater.inflate(R.layout.row_layout, null,true);
EditText RowNo = (EditText) rowView.findViewById(R.id.row_no);
EditText RowText = (EditText) rowView.findViewById(R.id.row_text);
RowNo.setText(rows.get(position).RowNo);
RowText.setText(rows.get(position).RowText);
return rowView;
}
}
public View getView (int position, View convertView, ViewGroup parent)
This method is called to get view object.
In your code there is GetView, not getView
change your
public View GetView(int position, View convertView, ViewGroup parent)
with
#Override
public View getView(int position, View convertView, ViewGroup parent)
and
holder.RowNo.setText(rows.get(position).RowNo);
with
holder.RowNo.setText(""+rows.get(position).RowNo);
I'm basically trying to display multiple views via the same ListView adapter. However, the adapter ends up generating multiple duplicates and crashes sometimes as well with a NullPointer. My guess is that I have implemented the adapter all wrong. Here's my complete code:
The item could either be a photo or a text.
Adapter:
public class FeedAdapter extends BaseAdapter {
static private Activity activity;
private static LayoutInflater inflater = null;
ArrayList<ActivityTable> actList = new ArrayList<ActivityTable>();
Holder holder;
public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
activity = a;
this.actList = actList;
}
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
final ActivityTable act = actList.get(position);
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
if (act.getType().equals("text")) {
convertView = inflater.inflate(R.layout.feed_single_text, null);
holder = new Holder();
//More code that Set the caption to the holder
convertView.setTag(holder);
}
if (act.getType().equals("photo")) {
convertView = inflater.inflate(R.layout.feed_single_picture, parent, false);
holder = new Holder();
holder.media = (ImageView) convertView.findViewById(R.id.postphoto);
//More code that Set the photo to the holder
convertView.setTag(holder);
}
} else {
holder = (Holder) convertView.getTag();
}
return convertView;
}
public static class Holder {
ImageView media;
TextView caption;
}
}
Am I inflating multiple views in the same adapter the wrong way? Can anyone point out the error?
You have 2 diffrent layout for each row so I think you should add
#Override
public int getViewTypeCount() {
return 2;
}
to your listview adapter
In your code, try to initial your LayoutInflater inside the constructor of your adapter
public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
...
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
And also you should optimize your ListView performance
Here is my experience
It is good to have these 3 in place.
#Override
public int getCount() {
return actList().size();
}
#Override
public Object getItem(int position) {
return actList().get(position);
}
#Override
public long getItemId(int position) {
return position;
}
Here is the important part,
first you have to tell the adapter how many type,
and then you have to tell the adapter how to determine the type.
Here I tell type View Type = 2
#Override
public int getViewTypeCount() {
return 2;
}
and Here I tell the adapter How I put the type number into the array
I use setType = 0 || set Type = 1
personal preference here: I like to use int instead of String
#Override
public int getItemViewType(int position) {
return act.get(position).getType();
}
and then later at the getView
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
int listViewItemType = getItemViewType(position);
if (v == null) {
..whatevever you doing to make v not null
}
if (listViewItemType == 0) {
//Do something
}else if(listViewItemType == 1){
// Do something different
}
return v;
}
Yes you will get duplicate Item, Because Convertview is reusing. Once convertview is created that view using if you scroll.
So better use single layout and with both Image and text. Based type hide any one.
xml file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/ImgFeed"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/txtCaption"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
try this you are using ImageView insted of TextView
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
final ActivityTable act = actList.get(position);
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.feed_layout, null);
holder = new Holder();
holder.caption = (TextView) convertView.findViewById(R.id.txtCaption);
holder.media = (ImageView) convertView.findViewById(R.id.ImgFeed);
if (act.getType().equals("text")) {
holder.media.setVisibility(View.GONE)
}
else if (act.getType().equals("photo")) {
holder.caption.setVisibility(View.GONE)
}
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
return convertView;
}
When I am checked any item like (position 0) its automatically checked randomly any item (like position 7) and when I scroll down or up the check position will be change every time... I am fed up from that problem...??
public class contactAdpter extends ArrayAdapter<ContactItem> {
Context context;
List<ContactItem> list;
public contactAdpter(Context context, int resource, List<ContactItem> items) {
super(context, resource,items);
this.context = context;
this.list = items;
}
static class ViewHolder {
ImageView imageview;
TextView tv1;
TextView tv2;
CheckBox ch;
}
#Override
public int getCount() {
return list.size();
}
#Override
public int getPosition(ContactItem item) {
return super.getPosition(item);
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
View view = convertView;
ContactItem contactItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = mInflater.inflate(R.layout.contact_list, null);
holder = new ViewHolder();
holder.tv1 = (TextView) view.findViewById(R.id.name);
holder.tv2 = (TextView) view.findViewById(R.id.number);
holder.ch = (CheckBox) view.findViewById(R.id.checkbox1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv1.setText(contactItem.getConatct_name());
holder.tv2.setText(contactItem.getNumber());
return view;
}
}
in ContactItem you need to maintain Checked Status. and change getView as follows,
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
View view = convertView;
ContactItem contactItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = mInflater.inflate(R.layout.contact_list, null);
holder = new ViewHolder();
holder.tv1 = (TextView) view.findViewById(R.id.name);
holder.tv2 = (TextView) view.findViewById(R.id.number);
holder.ch = (CheckBox) view.findViewById(R.id.checkbox1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv1.setText(contactItem.getConatct_name());
holder.tv2.setText(contactItem.getNumber());
holder.ch.setOnCheckedChangeListener(null);
holder.ch.setChecked(contactItem.getCheckedStatus());
holder.ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
contactItem.setCheckedStatus(isChecked);
}
});
return view;
}
you have to add another variable in ContactItem like below:
private boolean isSelected;
generate getter and setter method of this variable after that in your adapter :
public class contactAdpter extends ArrayAdapter {
Context context;
List<ContactItem> list;
public contactAdpter(Context context, int resource, List<ContactItem> items) {
super(context, resource,items);
this.context = context;
this.list = items;
}
static class ViewHolder {
ImageView imageview;
TextView tv1;
TextView tv2;
CheckBox ch;
}
#Override
public int getCount() {
return list.size();
}
#Override
public int getPosition(ContactItem item) {
return super.getPosition(item);
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
View view = convertView;
ContactItem contactItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = mInflater.inflate(R.layout.contact_list, null);
holder = new ViewHolder();
holder.tv1 = (TextView) view.findViewById(R.id.name);
holder.tv2 = (TextView) view.findViewById(R.id.number);
holder.ch = (CheckBox) view.findViewById(R.id.checkbox1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv1.setText(contactItem.getConatct_name());
holder.tv2.setText(contactItem.getNumber());
if(contactItem.isSelected){
holder.ch.isChecked(true);
} else {
holder.ch.isChecked(false);
}
holder.ch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(contactItem.isSelected){
holder.ch.isChecked(false);
contactItem.setChecked(false);
} else {
holder.ch.isChecked(true);
contactItem.setChecked(true);
}
notifyDatasetChanged();
}
});
return view;
}
}