I've a problem with listview in android, I've created a list view that takes data from SQLite database with a custom ArrayAdapter
I want to display an image view when user choose an item, but when I click on an item, the image (check mark) shows in 3 other items
I don't know where is the problem exactly, here is my code for adapter :
import info.androidhive.tabsswipe.R;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.itdinamik.tabswipe.CompareVehicle;
import com.itdinamik.vcompare.MySQLiteHelper;
import com.itdinamik.vcompare.Vehicle;
public class ComperAdapter extends ArrayAdapter<Vehicle>{
List<Vehicle> data;
Context context;
int layoutResID;
Vehicle itemdata;
MySQLiteHelper dbhelper;
public ComperAdapter(Context context, int layoutResourceId, List<Vehicle> data) {
super(context, layoutResourceId, data);
this.data=data;
this.context=context;
this.layoutResID=layoutResourceId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final NewsHolder holder;
View row = convertView;
dbhelper = new MySQLiteHelper(context);
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResID, parent, false);
holder = new NewsHolder();
holder.itemNameTitle = (TextView)row.findViewById(R.id.VehicleTxt);
holder.itemNameScore = (TextView)row.findViewById(R.id.Score);
holder.CheckedMark=(ImageView)row.findViewById(R.id.Checked);
holder.Vehicle=(ImageView)row.findViewById(R.id.Vehicle);
holder.RL = (RelativeLayout)row.findViewById(R.id.Rv);
row.setTag(holder);
}
else
{
holder = (NewsHolder)row.getTag();
}
//Toast.makeText(getContext(), String.valueOf(position +" - " + CompareVehicle.ClickedItem), Toast.LENGTH_SHORT).show();
if(CompareVehicle.ItemClieckd) {
if(position == CompareVehicle.ClickedItem) {
Log.w("Position", String.valueOf(position));
holder.CheckedMark.setVisibility(View.VISIBLE);
holder.RL.setBackgroundColor(Color.rgb(201, 50, 39));
}
}
itemdata = data.get(position);
holder.itemNameTitle.setText(itemdata.getTitle() + " - " + itemdata.getKraj() + " - "+ String.valueOf(position) + " - " + CompareVehicle.ClickedItem);
double totaldefault = itemdata.getOhranjenost()*0.25+itemdata.getPrevozeni()*0.16+
itemdata.getServis()*0.14+ itemdata.getCena()*0.13+
itemdata.getPoraba()*0.11+ itemdata.getStarost()*0.08+
itemdata.getDodatna()*0.07+ itemdata.getCenaZav()*0.06;
holder.itemNameScore.setText(String.format("%.1f",totaldefault));
return row;
}
static class NewsHolder{
TextView itemNameTitle;
TextView itemNameScore;
ImageView CheckedMark, Vehicle;
RelativeLayout RL;
}
}
and this one is for my fragment that i use to show my list view
import info.androidhive.tabsswipe.R;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.itdinamik.tabswipe.adapter.ComperAdapter;
import com.itdinamik.vcompare.MySQLiteHelper;
import com.itdinamik.vcompare.Vehicle;
public class CompareVehicle extends Fragment{
ViewPager mViewPager;
ArrayList<Vehicle> DataList;
static MySQLiteHelper dbhelper;
ComperAdapter adapter;
List<Vehicle> itemData;
ListView lv;
Button CompareButton;
int ClickedNum = 0;
public static int ClickedItem;
public static boolean ItemClieckd = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_compare_vehicle, container, false);
lv = (ListView)rootView.findViewById(R.id.CompareList);
CompareButton = (Button)rootView.findViewById(R.id.CompareButton);
dbhelper = new MySQLiteHelper(getActivity());
// get all vehicles
itemData = dbhelper.getAllVehicles();
adapter=new ComperAdapter(getActivity(),R.layout.list_single,itemData);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
ClickedItem = position;
ItemClieckd = true;
ClickedNum += 1;
adapter.notifyDataSetChanged();
/*RelativeLayout Rl = (RelativeLayout)arg1.findViewById(R.id.Rv);
ImageView CheckImg = (ImageView)arg1.findViewById(R.id.Checked);
Rl.setBackgroundColor(Color.rgb(201, 50, 39));
CheckImg.setVisibility(View.VISIBLE);*/
//Toast.makeText(getActivity(), String.valueOf(mSelectedItem), Toast.LENGTH_LONG).show();
}
});
CompareButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (ClickedNum < 2) {
Toast.makeText(getActivity(), "Please mark at least 2 items to compare them", Toast.LENGTH_LONG).show();
}
}
});
return rootView;
}
}
thank you
To avoid issues with view recycling in ListViews etc, I include a boolean for checked state in the item data List supplied to the constructor of the ArrayAdapter. I also provide my own interface for handling things like click events on child Views contained in my custom list item layout.
In my example below we handle a checkbox which can be clicked and also a label which can be long clicked:
public class MyListAdapter extends ArrayAdapter<MyItem> {
// interface for handling item child view events
public interface MyListAdapterListener {
void onItemCheckClicked(int index);
void onItemLabelLongClicked(int index);
}
private MyListAdapterListener mMyListAdapterListener;
int layoutResID;
// Constructor
public MyListAdapter(Context context, int resource, List<MyItem> myItems) {
super(context, resource, myItems);
layoutResID = resource;
}
public void setMyListAdapterListener(MyListAdapterListener listener) {
this.mMyListAdapterListener = listener;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// setup the row
View row;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
row = inflater.inflate(layoutResID, null);
} else {
row = convertView;
}
// setup the ViewHolder for this item
ViewHolder holder = (ViewHolder) row.getTag();
if (holder == null) {
holder = new ViewHolder(row);
row.setTag(holder);
}
// setup this item's label view
holder.label.setText(getItem(position).label);
// tag this item's label view with position so it can be retrieved in the onLongClick
holder.label.setTag(position);
// set the OnLongClickListener for the this item's label view
holder.label.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (mActivityListListener != null) {
// retrieve position from the view's tag, and trigger the listeners onItemLabelLongClicked method
mActivityListListener.onItemLabelLongClicked((Integer)v.getTag());
}
return false;
}
});
// setup this item's checkbox view
holder.checkbox.setChecked(getItem(position).myItemCheckBoolean);
// tag this item's checkbox view with position so it can be retrieved in the onClick
holder.checkbox.setTag(position);
// set the OnClickListener for the this item's checkbox view
holder.checkbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mMyListAdapterListener != null) {
// retrieve position from the view's tag, and trigger the listeners onItemCheckClicked method
mMyListAdapterListener.onItemCheckClicked((Integer) v.getTag());
}
}
});
return row;
}
class ViewHolder {
CheckBox checkbox = null;
TextView label = null;
ViewHolder(View row) {
this.checkbox = (CheckBox) row.findViewById(R.id.check_box);
this.label = (TextView) row.findViewById(R.id.item_label);
}
}
}
The MyItem class:
public class MyItem {
public String label;
public boolean myItemCheckBoolean;
}
Using the ArrayAdapter:
public class MyFragment extends Fragment {
....
private List<MyItem> myItems = new ArrayList<MyItem>();
....
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment__my_list, container, false);
lv = (ListView)rootView.findViewById(R.id.my_list);
// For example purposes, fill myItems with dummy data setting all checkboxes initially to false
for (int i = 0; i < 10; i++) {
MyItem myItem = new MyItem();
myItem.label = "Item " + i;
myItem.myItemCheckBoolean = false;
myItems.add(myItem);
}
MyListAdapter adapter = new MyListAdapter(getActivity(), R.layout.my_list_item, myItems);
adapter.setMyListAdapterListener( new MyListAdapter.MyListAdapterListener() {
#Override
public void onItemCheckClicked(int index) {
Log.d("MyFragment", "Item " + index + " Check Clicked");
// toggle the item's boolean
myItems.get(index).myItemCheckBoolean = !myItems.get(index).myItemCheckBoolean;
}
#Override
public void onItemLabelLongClicked(int index) {
Log.d("MyFragment", "Item " + index + " Label LongClicked");
}
}
lv.setAdapter(adapter);
....
return rootView;
}
Additional:
In response to your comment, you can use the adapter to customize the display of your list items as you wish. The version below shows how you might modify the adapter to use an ImageView instead of a CheckBox, and also changes the background color:
public class MyListAdapter extends ArrayAdapter<MyItem> {
// interface for handling item child view events
public interface MyListAdapterListener {
void onItemCheckClicked(int index);
void onItemLabelLongClicked(int index);
}
private MyListAdapterListener mMyListAdapterListener;
int layoutResID;
// Constructor
public MyListAdapter(Context context, int resource, List<MyItem> myItems) {
super(context, resource, myItems);
layoutResID = resource;
}
public void setMyListAdapterListener(MyListAdapterListener listener) {
this.mMyListAdapterListener = listener;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// setup the row
View row;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
row = inflater.inflate(layoutResID, null);
} else {
row = convertView;
}
// setup the ViewHolder for this item
ViewHolder holder = (ViewHolder) row.getTag();
if (holder == null) {
holder = new ViewHolder(row);
row.setTag(holder);
}
// setup this item's label view
holder.label.setText(getItem(position).label);
// tag this item's label view with position so it can be retrieved in the onLongClick
holder.label.setTag(position);
// set the OnLongClickListener for the this item's label view
holder.label.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (mActivityListListener != null) {
// retrieve position from the view's tag, and trigger the listeners onItemLabelLongClicked method
mActivityListListener.onItemLabelLongClicked((Integer)v.getTag());
}
return false;
}
});
// setup this item's image view based on the current state of the boolean
if (getItem(position).myItemCheckBoolean) {
holder.image.setImageResource(R.drawable.image_a);
} else {
holder.image.setImageResource(R.drawable.image_b);
}
// tag this item's image view with position so it can be retrieved in the onClick
holder.image.setTag(position);
// set the OnClickListener for the this item's image view
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mMyListAdapterListener != null) {
// retrieve position from the view's tag, and trigger the listeners onItemCheckClicked method
mMyListAdapterListener.onItemCheckClicked((Integer) v.getTag());
}
}
});
// setup this item's background based on the current state of the boolean
if (getItem(position).myItemCheckBoolean) {
holder.layout.setBackgroundColor(Color.red);
} else {
holder.layout.setBackgroundColor(Color.white);
}
return row;
}
class ViewHolder {
ImageView image = null;
TextView label = null;
RelativeLayout layout = null;
// constructor
ViewHolder(View row) {
this.image = (ImageView) row.findViewById(R.id.item_image);
this.label = (TextView) row.findViewById(R.id.item_label);
this.layout = (RelativeLayout) row.findViewById(R.id.item_layout)
}
}
}
Related
i"m using custom list have two buttons, one for and second one for whatsaap. my problem is when i"m click first button then make a phone call its not working for me... please help me
custom list :
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Movie> movieItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<Movie> movieItems) {
this.activity = activity;
this.movieItems = movieItems;
}
#Override
public int getCount() {
return movieItems.size();
}
#Override
public Object getItem(int location) {
return movieItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView rating = (TextView) convertView.findViewById(R.id.rating);
TextView genre = (TextView) convertView.findViewById(R.id.genre);
Button year = (Button) convertView.findViewById(R.id.releaseYear);
year.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity, "ramu...", Toast.LENGTH_LONG).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:123456789"));
startActivity(callIntent);
}
});
// getting movie data for the row
Movie m = movieItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
System.out.println("thumbNail===============>"+thumbNail);
// title
title.setText(m.getTitle());
// rating
rating.setText("Rating: " + String.valueOf(m.getRating()));
// release year
year.setText(String.valueOf(m.getYear()));
return convertView;
}
private void startActivity(Intent callIntent) {
// TODO Auto-generated method stub
}
}
`
You are committing few mistakes which cannot be ignored.
Listview recycles views on scroll, so it is very important that you handle this check. Not doing so will cause views inflation at wrong positions. Use ViewHolder
Solution:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
/* This is where you initialize new rows, by:
* - Inflating the layout,
* - Instantiating the ViewHolder,
* - And defining any characteristics that are consistent for every row */
} else {
/* Fetch data already in the row layout,
* primarily you only use this to get a copy of the ViewHolder */
}
/* Set the data that changes in each row, like `title` and `size`
* This is where you give rows there unique values. */
return convertView;
}
You need to implement OnClickListener outside of checks like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_row, null);
NetworkImageView thumbNail = (NetworkImageView) convertView
.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView rating = (TextView) convertView.findViewById(R.id.rating);
TextView genre = (TextView) convertView.findViewById(R.id.genre);
Button year = (Button) convertView.findViewById(R.id.releaseYear);
}else {
}
year.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity, "ramu...", Toast.LENGTH_LONG).show();
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:123456789"));
startActivity(callIntent);
}
});
// getting movie data for the row
Movie m = movieItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
System.out.println("thumbNail===============>"+thumbNail);
// title
title.setText(m.getTitle());
// rating
rating.setText("Rating: " + String.valueOf(m.getRating()));
// release year
year.setText(String.valueOf(m.getYear()));
return convertView;
}
Initialize ImageLoader in adapter constructor:
I'm using HeaderListView and I'm getting a ArrayIndexOutOfBoundsException as expected when you try to access the position -1 of any Array. But here goes my point, I'm getting this error inside the framework code, more precisely a this line:
boolean prevHasRows = mAdapter.numberOfRows(actualSection - 1) > 0;
inside the file HeaderListView
I tried to hack it and put something like:
boolean prevHasRows = mAdapter.numberOfRows(actualSection - 1) > 0;
Here I got no more ArrayIndexOutOfBoundsException, but when I have a list big enough to scroll, the least items got messed, I got itens from the first section inside the last.
Here goes my the code:
Fragment where I setup the adapter:
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import br.com.soutsapp.souts.R;
import br.com.soutsapp.souts.model.Menu;
import br.com.soutsapp.souts.model.Product;
import br.com.soutsapp.souts.model.modelview.OrderItem;
import br.com.soutsapp.souts.userInterface.adapter.SectionAdapter;
import br.com.soutsapp.souts.userInterface.controls.HeaderListView;
public class MenuFragment extends Fragment {
private Context mContext;
private List<OrderItem> itens;
private Menu menu;
public MenuFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_menu, container, false);
mContext = getContext();
itens = new ArrayList<>();
menu = new Menu();
setUpCardListView(v);
return v;
}
private void setUpCardListView(View v){
HeaderListView list = (HeaderListView) v.findViewById(R.id.hlv_card_items);
list.setAdapter(new SectionAdapter() {
#Override
public int numberOfSections() {
return menu.getMenuSessions().size();
}
#Override
public int numberOfRows(int section) {
return menu.getMenuSessions().get(section).size();
}
#Override
public Object getRowItem(int section, int row) {
return menu.getMenuSessions().get(section).get(row);
}
#Override
public boolean hasSectionHeaderView(int section) {
return true;
}
#Override
public View getRowView(final int section, final int row, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(getResources().getLayout(R.layout.menu_item_row), null);
TextView tvMenuItemName = (TextView) convertView.findViewById(R.id.tv_menu_item_name);
TextView tvMenuItemPrice = (TextView) convertView.findViewById(R.id.tv_price);
String itemName = menu.getMenuSessions().get(section).get(row).getName();
tvMenuItemName.setText(itemName);
String itemPrice = String.valueOf(menu.getMenuSessions().get(section).get(row).getPrice());
tvMenuItemPrice.setText(itemPrice);
TextView tvQuantity = (TextView) convertView.findViewById(R.id.tv_quantity);
tvQuantity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView tvQuantity = (TextView) v;
Product product = (Product) getRowItem(section, row);
if (tvQuantity.getText().equals("1") && !tvQuantity.getText().equals("")){
tvQuantity.setText("");
OrderItem itenToRemove = null;
for(OrderItem item: itens){
if(item.getProductId() == product.getId()){
itenToRemove = item;
break;
}
}
itens.remove(itenToRemove);
}
else{
for(OrderItem item: itens){
if(item.getProductId() == product.getId()){
int quantity = item.getQuantity();
item.setQuantity(--quantity);
tvQuantity.setText(String.valueOf(item.getQuantity()));
break;
}
}
}
}
});
}
return convertView;
}
#Override
public int getSectionHeaderViewTypeCount() {
return 1;
}
#Override
public View getSectionHeaderView(int section, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(getResources().getLayout(android.R.layout.simple_list_item_1), null);
}
switch (section) {
case 0:
((TextView) convertView).setText("Bebidas");
convertView.setBackgroundColor(getResources().getColor(R.color.Blue_Jay));
break;
case 1:
((TextView) convertView).setText("Comidas");
convertView.setBackgroundColor(getResources().getColor(R.color.Red_Wine));
break;
case 2:
((TextView) convertView).setText("Diversos");
convertView.setBackgroundColor(getResources().getColor(R.color.Camel_brown));
break;
}
return convertView;
}
#Override
public void onRowItemClick(AdapterView<?> parent, View view, int section, int row, long id) {
super.onRowItemClick(parent, view, section, row, id);
TextView tvQuantity = (TextView) view.findViewById(R.id.tv_quantity);
Product p = (Product) getRowItem(section, row);
boolean exist = false;
for(OrderItem item : itens){
if(item.getProductId() == p.getId()){
int actualQuantity = item.getQuantity();
item.setQuantity(++actualQuantity);
tvQuantity.setText(String.valueOf(item.getQuantity()));
exist = true;
}
}
if(!exist){
itens.add(new OrderItem(p.getId(), 1));
tvQuantity.setText("1");
}
}
});
}
}
Thanks in advance folks!
I have the same problem, I solved it by modify the SectionAdapter.java
Like below:
public abstract int numberOfRows(int section);
public int numberOfRow(int section) {
if(section < 0) {
return 0;
}
return this.numberOfRows(section);
}
Then, in the HeaderListView that you had mentioned, modify it to call
boolean currIsLast = mAdapter.getRowInSection(realFirstVisibleItem) == mAdapter.numberOfRow(actualSection) - 1;
boolean prevHasRows = mAdapter.numberOfRow(actualSection - 1) > 0;
Now we solve the bug.
I have been fighting with this problem for days. Looking for the solution on stackoverflow or anywhere a solution is given, tried all of them even tried recyclerView but nothing helped.
My PROBLEM is that I've a listview and two textView on a listItem. So whenever I click on list item, Visibility of one textView is GONE. But when I scroll down I see not only clicked one is gone but many others are gone as well.
Heres my code
CustomAdapter.java class
package com.example.nara.testtt;
import android.content.Context;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.
import java.util.ArrayList;
public class CustomAdapter extends BaseAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
public CustomAdapter(Context context){
this.context = context;
for(int i = 0; i < 50; i++){
list.add("item at " + i);
}
}
#Override
public int getCount() {
return list.size();
}
#Override
public String getItem(int position) {
return list.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
LayoutInflater inflator = LayoutInflater.from(context);
convertView = inflator.inflate(R.layout.list_item,null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else{
holder = (ViewHolder)convertView.getTag();
}
holder.tv1.setText(getItem(position));
holder.tv2.setText(getItem(position));
return convertView;
}
public static class ViewHolder{
private TextView tv1;
private TextView tv2;
public ViewHolder(View view){
tv1 = (TextView) view.findViewById(R.id.textView);
tv2 = (TextView) view.findViewById(R.id.textView2);
}
}
}
MainActivity.java
package com.example.nara.testtt;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new CustomAdapter(this);
ListView lv = (ListView) findViewById(R.id.listView);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setVisibility(View.GONE);
adapter.notifyDataSetChanged();
}
});
}
#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);
}
}
In getView() after setting the text update the visibility of the textview to Visible, since listitems in the ListView will get recycled.
holder.tv1.setText(getItem(position));
holder.tv2.setText(getItem(position));
holder.tv1.setVisibility(View.VISIBLE);
//Your code.....
Updated :
public class CustomAdapter extends BaseAdapter {
private ArrayList list = new ArrayList();
private Context context;
public CustomAdapter(Context context) {
this.context = context;
for (int i = 0; i < 50; i++) {
list.add(new Bean("item at " + i));
}
}
#Override
public Bean getItem(int position) {
return list.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Initialization .......
Bean item = getItem(position);
holder.tv1.setText(item.name);
holder.tv2.setText(item.name);
holder.tv1.setVisibility(item.visibility);
return convertView;
}
// ViewHolder declaration
.......
public static class Bean {
String name;
int visibility = View.VISIBLE;
public Bean(String name) {
this.name = name;
}
}
In the onItemClick on your activity.
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView tv = (TextView) view.findViewById(R.id.textView);
Bean bean = Adapter.getItem(position);
bean.visibility = View.GONE
tv.setVisibility(View.GONE);
adapter.notifyDataSetChanged();
}
The problem is that the views are getting recycled in your adapter. So when you are scrolling the old views are getting used for the new ones. That means if the visibility of the items of the old view are set to GONE are still GONE in the new ones. If you dont want to save the visibility you can just set them to visible in your adapter:
holder.tv1.setVisibility(View.VISIBLE);
holder.tv1.setText(getItem(position));
holder.tv2.setText(getItem(position));
Or you store boolean values in a list or something like that and ask there if the item was clicked:
if(clicked.get(i)) holder.tv1.setVisibility(View.GONE);
else holder.tv1.setVisibility(View.VISIBLE);
Replace
convertView = inflator.inflate(R.layout.list_item,null);
with
convertView = inflator.inflate(R.layout.list_item,container,false);
Im attempting to add two different views to the GridviewLayoutManager using a custom adapter.
However, I cant seem to reference the headerview correctly. When the onbindViewHolder is called it is expecting a "ViewHolder" response, however i really want to reference the HeaderView i crated
Because I cant access the correct view, I also cant reference the TextView within the XML layout I am calling.
here is my customer adaptor class:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class ElementsAdapter extends RecyclerView.Adapter<ElementsAdapter.ViewHolder> {
private ArrayList<String> mDataset;
private ArrayList<Integer> mDatamap;
public Context context;
private static final int VIEW_HEADER = 0;
private static final int VIEW_NORMAL = 1;
private View headerView;
private int datasetSize;
public class HeaderHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView headertext;
public HeaderHolder(View v) {
super(v);
headertext = (TextView) v.findViewById(R.id.headertext);
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView txtHeader;
public TextView txtFooter;
public ImageView imgImage;
public ViewHolder(View v) {
super(v);
txtHeader = (TextView) v.findViewById(R.id.firstLine);
txtFooter = (TextView) v.findViewById(R.id.secondLine);
imgImage = (ImageView) v.findViewById(R.id.icon);
}
}
public ElementsAdapter(ArrayList<String> myDataset, ArrayList<Integer> myDatamap) {
mDataset = myDataset;
myDatamap = mDatamap;
}
#Override
public int getItemViewType(int position) {
return isHeader(position) == 1 ? VIEW_HEADER : VIEW_NORMAL;
}
#Override
public int getItemCount() {
return mDataset.size();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_HEADER) {
// create a new view
View sub_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false);
Context context = sub_view.getContext();
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(sub_view);
return vh;
// return new HeaderViewHolder(headerView);
} else {
// create a new view
View sub_view = LayoutInflater.from(parent.getContext()).inflate(R.layout.sub_layout, parent, false);
context = sub_view.getContext();
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(sub_view);
return vh;
}
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
if (isHeader(position) == 1) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final String name = mDataset.get(position);
// holder.txtHeader.setText(mDataset.get(position));
viewHolder.headertext.setText(name);
} else {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final String name = mDataset.get(position);
Picasso.with(context).load("http://www.500kgiveaway.co.uk/"+name).resize(200,200).into(viewHolder.imgImage);
// holder.txtHeader.setText(mDataset.get(position));
viewHolder.txtHeader.setText(name);
viewHolder.txtHeader.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
//remove(name);
}
}
);
viewHolder.txtFooter.setText("Footer: "+mDataset.get(position));
}
//ViewHolder holder = (ViewHolder) viewHolder;
//holder.textView.setText("Position " + (position - 1));
}
public int isHeader(int position) {
return mDatamap.get(position) ==1 ? 1:0;}
}
It seems to me that the isHeader() method will always return 0, since you compare a String with a integer. I assume you would like want to check the position of the current item to be 1.
Try this code instead:
public boolean isHeader(int position) {
return position == 1;
}
Then replace
if (isHeader(position) == 1)...
with
if (isHeader(position))...
I hope this helps.
Edit
The above was intended. Sorry.
In the class definition ElementsAdapter.ViewHolder is inserted as the ViewHolder type. This works for the normal
ElementsAdapter.ViewHolder extends RecyclerView.ViewHolder
but not for
ElementsAdapter.HeaderHolder extends RecyclerView.ViewHolder
since it doesn't extend ElementsAdapter.ViewHolder.
You should therfore specify RecyclerView.ViewHolder instead as a generic type to support both of your types.
i have developed an application that have one list view and that list view's one item contain one image view one text view and one check box so my question is how to handle check box checked and unchecked event of particular list view item
Adapter class for list view
package com.rk.test_facebook;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class ListAdapter extends BaseAdapter {
private ArrayList<String> imageUrl;
private final ArrayList<String> name;
private final ArrayList<String> birthday;
private Activity activity;
private static LayoutInflater inflater = null;
public ImageLoader imageLoader;
public ListAdapter(Activity activity, ArrayList<String> imageUrl, ArrayList<String> birthday, ArrayList<String> name) {
this.activity = activity;
this.imageUrl = imageUrl;
this.name = name;
this.birthday = birthday;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return name.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 view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.listelement, null);
TextView text = (TextView) view.findViewById(R.id.text);
ImageView image = (ImageView) view.findViewById(R.id.image);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
text.setText((name.get(position)));
imageLoader.DisplayImage(imageUrl.get(position), image);
return view;
}
}
main activity
package com.rk.test_facebook;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import Handler.DatabaseHandler;
import Property.FriendsProperty;
/**
* Created by Intex on 15/04/2014.
*/
public class FriedsList extends Activity {
private ListView listView;
public static ArrayList<String> arrayListName = new ArrayList<String>();
public static ArrayList<String> arrayListBirthday = new ArrayList<String>();
public static ArrayList<String> arrayListImage = new ArrayList<String>();
private ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.friendslist);
listView = (ListView) findViewById(R.id.ListView);
DatabaseHandler databaseHandler = new DatabaseHandler(this);
ArrayList<FriendsProperty> properties = databaseHandler.DislpayFriends();
for (FriendsProperty friendsProperty : properties) {
arrayListName.add(friendsProperty.getName());
arrayListImage.add(friendsProperty.getImage());
arrayListBirthday.add(friendsProperty.getBirthday());
}
databaseHandler.close();
adapter = new ListAdapter(this, arrayListImage, arrayListBirthday, arrayListName);
listView.setAdapter(adapter);
}
}
Change the code getView() call back as below,
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.listelement, null);
TextView text = (TextView) view.findViewById(R.id.text);
ImageView image = (ImageView) view.findViewById(R.id.image);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
// it is check
} else {
// it is unchecked
}
}
});
text.setText((name.get(position)));
imageLoader.DisplayImage(imageUrl.get(position), image);
return view;
}
The method in the getView() you must add an setOnCheckedChangeListener as follows
checkBox.setOnCheckedChangeListener(starCheckedChangeListener);
}
private OnCheckedChangeListener starCheckedChangeListener = new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked)
{
//DO WHEN CHECKED
}
else
{
//Do when not checked
}
}
};
Change the code to below to add the checked item in array.
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null)
view = inflater.inflate(R.layout.listelement, null);
TextView text = (TextView) view.findViewById(R.id.text);
ImageView image = (ImageView) view.findViewById(R.id.image);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
selectedItemArrayList.add(dataArrayList.get(position));
} else {
selectedItemArrayList.remove(dataArrayList.get(position));
}
}
});
text.setText((name.get(position)));
imageLoader.DisplayImage(imageUrl.get(position), image);
return view;
}