Hello my friends I have a problem. When I scroll down in my GridView and scroll up the order of the items changes. I want all itmes to stay on the same place. Below you can find my code. It would be nice if someone can help me out as this is a very irritating bug.
public class GridAdapter extends BaseAdapter {
Context context;
private final String [] data;
View view;
LayoutInflater layoutInflater;
int[] i = {
R.drawable.blue,
R.drawable.green,
R.drawable.yellow,
};
public GridAdapter(Context context, String[] data) {
this.context = context;
this.data = data;
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = new View(context);
view = layoutInflater.inflate(R.layout.single_item,null);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
TextView textView = (TextView) view.findViewById(R.id.textView);
Random rand = new Random();
int n = rand.nextInt(i.length);
imageView.setImageResource(i[n]);
textView.setText(data[position]);
}else{
view = (View)convertView;
}
return view;
} }
to faster the performance use ViewHolder like below
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
convertView = layoutInflater.inflate(R.layout.single_item, null);
final ImageView imageView = (ImageView)convertView.findViewById(R.id.imageView);
final TextView textView = (TextView)convertView.findViewById(R.id.textView);
final ViewHolder viewHolder = new ViewHolder(imageView, textView);
convertView.setTag(viewHolder);
}
Random rand = new Random();
int n = rand.nextInt(i.length);
final ViewHolder viewHolder = (ViewHolder)convertView.getTag();
viewHolder.imageView.setImageResource(i[n]);
viewHolder.textView.setText(data[position]);
return convertView;
}
private class ViewHolder {
private final TextView imageView;
private final TextView textView;
public ViewHolder(TextView imageView, TextView textView) {
this.imageView = imageView;
this.textView = textView;
}
}
It worked for me after adding those 2 lines:
#Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
Related
I would like to display video from database into a grid view i managed to do it with images but have no idea how to do it with a videoview , i would like to do the same but for videos
public class Photoadapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<Photo> photoList;
#Override
public int getCount() {
return photoList.size();
}
#Override
public Object getItem(int position) {
return photoList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
ImageView imageView;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
View row = view;
ViewHolder holder = new ViewHolder();
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(layout, null);
holder.imageView = (ImageView) row.findViewById(R.id.imageViewList);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
final Photo photo = photoList.get(position);
final byte[] photoImage = photo.getImage();
final Bitmap bitmap = BitmapFactory.decodeByteArray(photoImage, 0, photoImage.length);
holder.imageView.setImageBitmap(bitmap);
return row;
}
public Photoadapter(Context context, int layout, ArrayList<Photo> photoList) {
this.context = context;
this.layout = layout;
this.photoList = photoList;
}
}
public class ListViewAdapter extends BaseAdapter {
private Context context;
private LocationDetails[] locationDetails;
public ListViewAdapter(Context c, LocationDetails[] locationDetails) {
context = c;
this.locationDetails = locationDetails;
}
#Override
public int getCount() {
return locationDetails.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View list;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (view == null) {
list = new View(context);
list = inflater.inflate(R.layout.listview_layout, null);
TextView name = (TextView) list.findViewById(R.id.location_name);
TextView desc = (TextView) list.findViewById(R.id.location_desc);
ImageView img = (ImageView) list.findViewById(R.id.location_image);
name.setText(locationDetails[i].getLocationName());
desc.setText(locationDetails[i].getLocationDesc());
img.setImageResource(locationDetails[i].getLocationIcon());
} else {
list = (View) view;
}
return list;
}
}
This code is the code before I use viewholder, it works fine. Then I tried to modify it with the use of viewholder, and compile it with gradle, all the image and textviews disappeared, I don't know what's wrong with the code below. Why can't I get any thing shown on the screen?
public class LocationAdapter extends BaseAdapter {
private Context context;
private LocationDetails[] locationDetails;
public LocationAdapter(Context c, LocationDetails[] locationDetails) {
context = c;
this.locationDetails = locationDetails;
}
#Override
public int getCount() {
return locationDetails.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View list = view;
ViewHolder vh;
if (list == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
list = inflater.inflate(R.layout.listview_layout, null);
vh = new ViewHolder();
vh.name = (TextView) list.findViewById(R.id.location_name);
vh.desc = (TextView) list.findViewById(R.id.location_desc);
vh.img = (ImageView) list.findViewById(R.id.location_image);
list.setTag(vh);
} else {
vh = (ViewHolder) list.getTag();
}
return list;
}
static class ViewHolder {
TextView name;
TextView desc;
ImageView img;
}
}
public class LocationAdapter extends BaseAdapter {
private Context context;
private LocationDetails[] locationDetails;
Object model;
public LocationAdapter(Context c, LocationDetails[] locationDetails) {
context = c;
this.locationDetails = locationDetails;
}
#Override
public int getCount() {
return locationDetails.length;
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View list = view;
ViewHolder vh;
if (list == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
list = inflater.inflate(R.layout.listview_layout, null);
vh = new ViewHolder();
vh.name = (TextView) list.findViewById(R.id.location_name);
vh.desc = (TextView) list.findViewById(R.id.location_desc);
vh.img = (ImageView) list.findViewById(R.id.location_image);
list.setTag(vh);
} else {
vh = (ViewHolder) list.getTag();
}
model = getItem(i);
vh.name.setText(model.getLocationName());
vh.desc.setText(model.getLocationDesc());
// same as image...
return list;
}
static class ViewHolder {
TextView name;
TextView desc;
ImageView img;
}
}
There is a sample baseadapter as follows and it uses a layout xml file names adapter_layout. But I do not want to use the adapter_layout.xml. I want to identify with all components(TextView, EditText ...) in the class. How should the BaseAdapter coding programmatically without adapter_layout.xml?
public class LayoutAdapter extends BaseAdapter {
private List<String> objects = new ArrayList<String>();
private Context context;
private LayoutInflater layoutInflater;
public LayoutAdapter(Context context) {
this.context = context;
this.layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return objects.size();
}
#Override
public String getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.adapter_layout, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.textView2 = (TextView) convertView.findViewById(R.id.textView2);
viewHolder.textView1 = (TextView) convertView.findViewById(R.id.textView1);
viewHolder.editText1 = (EditText) convertView.findViewById(R.id.editText1);
convertView.setTag(viewHolder);
}
return convertView;
}
protected class ViewHolder {
private TextView textView2;
private TextView textView1;
private EditText editText1;
}
}
Im using a listView that have 2 layouts for the rows on one row the
setOnItemClickListener
but on the other row it doesnt recognize the taps,
public void initItemTable()
{
listViewItem = (ListView) getView().findViewById(R.id.listViewItem);
listViewItem.setAdapter(new PhoneItemAdapter(new ItemPhoneDataSource().getItems()));
listViewItem.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
Log.d("mensa", "item index :"+arg2);
}
});
}
//
private class PhoneItemAdapter extends BaseAdapter {
final List<RowPhone> rows;//row
//data source, style
PhoneItemAdapter(List<ItemPhone> animals) {
rows = new ArrayList<RowPhone>();//member variable
//choose cell! iterator
for (ItemPhone item : animals) {
if (item.getType().equals("item")) {
rows.add(new RowItemPhone(LayoutInflater.from(getActivity()), item));
} else {
rows.add(new RowFolderPhone(LayoutInflater.from(getActivity()), item)); //imageRow!
}
}
}
//delegate
#Override
public int getViewTypeCount() {
return RowTypePhone.values().length;
}
#Override
public int getItemViewType(int position) {
//con cast
return ((RowPhone) rows.get(position)).getViewType();
}
public int getCount() {
return rows.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
//cambiado con cast!
return ((RowPhone) rows.get(position)).getView(convertView);
}
}
So the tap is detected when "item.getType()" is folder but not in item,
. Shall I include the code for RowItemPhone.java and RowFolderPhone.java?
so how to fix this tap problem?
thanks!
edit 1. RowPhone.java
public interface RowPhone {
public View getView(View convertView);
public int getViewType();
}
edit 2. RowFolder.java .. the one that have the tap detecting fine:
public class RowItemPhone implements RowPhone{
private final ItemPhone item;
private final LayoutInflater inflater;
public RowItemPhone(LayoutInflater inflater, ItemPhone animal) {
this.item = animal;
this.inflater = inflater;
}
//text doble
public View getView(View convertView) {
ViewHolder holder;
View view = null;
if (convertView == null) {
//ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_item_phone, null);
ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_item_phone, (ViewGroup) view, false);
holder = new ViewHolder(
(ImageView)viewGroup.findViewById(R.id.image_item),
(TextView)viewGroup.findViewById(R.id.title),
(TextView)viewGroup.findViewById(R.id.description));
viewGroup.setTag(holder); //pa q y como usa tag!
view = viewGroup;
} else {
view = convertView;
holder = (ViewHolder)convertView.getTag();
}
//setup
holder.imageView.setImageResource(item.getImageId());
holder.descriptionView.setText(item.getDescription());
holder.titleView.setText(item.getName());
return view;
}
public int getViewType() {
return RowTypePhone.DESCRIPTION_ROW.ordinal();
}
private static class ViewHolder {
final ImageView imageView;
final TextView titleView;
final TextView descriptionView;
private ViewHolder(ImageView imageView, TextView titleView, TextView descriptionView) {
this.imageView = imageView;
this.titleView = titleView;
this.descriptionView = descriptionView;
}
}
}
And here the RowFolderPhone.java ... showing fine, but not detecting taps:
public class RowFolderPhone implements RowPhone {
private final ItemPhone item;
private final LayoutInflater inflater;
public RowFolderPhone(LayoutInflater inflater, ItemPhone animal) {
this.item = animal;
this.inflater = inflater;
}
public View getView(View convertView) {
ViewHolder holder;
View view = null;
//we have a don't have a converView so we'll have to create a new one
if (convertView == null) {
// ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_folder_phone, null);
ViewGroup viewGroup = (ViewGroup)inflater.inflate(R.layout.row_folder_phone, (ViewGroup) view, false);
//use the view holder pattern to save of already looked up subview
holder = new ViewHolder((ImageView)viewGroup.findViewById(R.id.image),
(TextView)viewGroup.findViewById(R.id.title));
viewGroup.setTag(holder);
view = viewGroup;
} else {
//get the holder back out
holder = (ViewHolder)convertView.getTag();
view = convertView;
}
//actually setup the view
holder.imageView.setImageResource(item.getImageId());
holder.titleView.setText(item.getName());
return view;
}
public int getViewType() {
return RowTypePhone.IMAGE_ROW.ordinal();
}
private static class ViewHolder {
final ImageView imageView;
final TextView titleView;
private ViewHolder(ImageView imageView, TextView titleView) {
this.imageView = imageView;
this.titleView = titleView;
}
}
}
There are something wrong with your getItem method on PhoneItemAdapter. getItem method should return list item not position. So you should replace your code to
public RowPhone getItem(int position) {
return rows.get(position);
}
the problem was solved by setting descendantFocusability
in : row_item_phone.xml
<RelativeLayout ...
android:descendantFocusability="blocksDescendants"
i have fragment in which i have a listview , i was trying to show some data in the list . it is silly but its not working i have no idea what is wrong with it.
in my fragmnet in oncreateview im doing this
mContactsHomeAdapter = new ContactsHomeAdapter(getActivity());
mListView.setAdapter(mContactsHomeAdapter);
mContactsHomeAdapter.notifyDataSetChanged();
this is my adapter code
public class ContactsHomeAdapter extends BaseAdapter {
ExecutorService executorService;
private Context mContext;
LayoutInflater mInflater;
public ContactsHomeAdapter(Context pContext) {
mContext = pContext;
//executorService=Executors.newFixedThreadPool(10);
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return 100;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = mInflater.inflate(R.layout.contacts_adapter_item, null);
}
CheckBox lCheckbox = (CheckBox) convertView.findViewById(R.id.check_box);
TextView lContactTitle = (TextView) convertView.findViewById(R.id.contact_title);
TextView lContactEmail = (TextView) convertView.findViewById(R.id.contact_email);
ImageView lContactPhoto = (ImageView) convertView.findViewById(R.id.contact_photo);
TextView lContactNumber = (TextView) convertView.findViewById(R.id.contact_phonenumber);
lContactTitle.setText("hello");
// QueueItem lItem = new QueueItem() ;
// lItem.mId = ""+position;
// lItem.mName = lContactTitle;
// lItem.mNumber = lContactNumber;
// lItem.mEmail = lContactEmail;
// executorService.submit(new QueueRunner(lItem));
return convertView;
}
}