i have an extended baseadapter class which i'm using for populating listview.
i want to change visibility of an element in another layout file(parent file containing listview element) but i'm unable to find a suitable solution.
i tried setting second inflater, executing another class and in fragment but to no avail. however click is detected fine since i'm able to log that in console
convertView = layoutInflater.inflate(R.layout.list_main, null);
final View convertView1 = layoutInflater.inflate(R.layout.tab_fragment_1, null);
that wont work obviously because we could return only one view so i tried declaring another class but still same result
for some reason i'm unable to register click in mainactivity. even that could help
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
System.out.println("ArrayList Of Vssalues :");
}
});
baseadapter getview class
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_main, null);
final View convertView1 = layoutInflater.inflate(R.layout.tab_fragment_1, null);
final RelativeLayout calendartoshow = (RelativeLayout) row.findViewById(R.id.calendarlay);
final RelativeLayout list_menu = (RelativeLayout) convertView.findViewById(R.id.list_menu);
Button list_but = (Button) list_menu.findViewById(R.id.book_button);
holder = new ViewHolder();
//getView1();
holder.icon = (ImageView)convertView.findViewById(R.id.image);
holder.icon.setImageResource(listData[position]);
holder.text = (TextView)convertView.findViewById(R.id.textv);
final Button holder_but = (Button)convertView.findViewById(R.id.book_button);
holder_but.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
calendartoshow.setVisibility(View.VISIBLE);
System.out.println("ArrayLissst Of Values :");
//new clickclass();
// getView1(position,convertView1,parent);
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(TEXTS[position]);
return convertView;
}
Related
I have a custom listview with a button to add more elements
but when I add and element the app crash, but when I restart I find that the element is added, (rarely it doesn't crash)
And i
I use custom adapter
class CustomAdapter extends BaseAdapter {
ArrayList<ListItem> listItems = new ArrayList<ListItem>();
CustomAdapter(ArrayList<ListItem> list){
this.listItems = list;
}
#Override
public int getCount() {
return listItems.size();
}
#Override
public Object getItem(int position) {
return listItems.get(position).name;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int i, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.list_item,null);
TextView name = (TextView) view.findViewById(R.id.name);
TextView lastm = (TextView) view.findViewById(R.id.last);
TextView time = (TextView) view.findViewById(R.id.time);
CircleImageView pic= (CircleImageView) view.findViewById(R.id.pic);
name.setText(listItems.get(i).name);
lastm.setText(listItems.get(i).lastm);
time.setText(listItems.get(i).time);
Bitmap bmp = BitmapFactory.decodeByteArray(listItems.get(i).pic,0,listItems.get(i).pic.length);
pic.setImageBitmap(bmp);
return view;
}
}
and when I add an element the app crashs
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText editText=(EditText) mView.findViewById(R.id.name);
String name=editText.getText().toString();
boolean result=myDataBase.insertData(imageViewToByte(img),name,"no messages yet","");
if (result) {
Toast.makeText(Main2Activity.this, "Saved in DATABASE", Toast.LENGTH_SHORT).show();
viewLastData();
dialog.dismiss();
}
If your ListView lags it's because you used wrap_content for the listView's layout_height. It forces your ListView to count all the items inside and it has a huge performance impact.
So replace wrap_content by match_parent to avoid those lags.
EDIT: Use a ViewHolder pattern too in your Adapter, see this link.
Here is an example:
// ViewHolder Pattern
private static class ViewHolder {
TextView name, status;
}
#Override #NonNull
public View getView(int position, View convertView, #NonNull ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater vi = LayoutInflater.from(getContext());
convertView = vi.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.text_name);
holder.status = (TextView) convertView.findViewById(R.id.another_text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Then do the other stuff with your item
// to populate your listView
// ...
return convertView
}
I've searched for this question already, and I couldn't find it anywhere, and I'm not even sure how to exactly word it.
I have a listview with images, text, buttons, etc. for each item. I also have an edittext for the items, but I only want the edittext to be visible for the current user. The same way you're only able to edit your own post on Facebook, not every other one as well.
Here's what I've tried:
holder.editcaption = (EditText) itemView.findViewById(R.id.editText1);
(...)
if(mCurrentUser.getUsername()!=currentItem.getSender())
holder.editcaption.setVisibility(View.INVISIBLE);
This is in the getView() of the adapter. The problem is that either all of the edittexts become invisible or visible when I only need every edittext except for the current user's to be invisible. I only need the edittext view of the current item to change.
Any help is very much appreciated.
private class MyListAdapter extends ArrayAdapter<GalleryItem>{
public MyListAdapter(){
super(getActivity(), R.layout.item_view, thelist);
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
if(items.get(position).getUsername()!=mCurrentUser.getUsername())
return 2;
else return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
currentItem = adapter.getItem(position);
int type = getItemViewType(position);
ViewHolder holder;
View itemView = null;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) getListView().getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
if(type==0)
itemView = inflater.inflate(R.layout.item_view, parent, false);
else
itemView = inflater.inflate(R.layout.currentuser_item_view, parent, false);
holder = new ViewHolder();
holder.image = (ImageView)itemView.findViewById(R.id.imgAvatar);
holder.text = (TextView) itemView.findViewById(R.id.newtext);
holder.profilepicture = (ProfilePictureView) itemView.findViewById(R.id.profilePicture);
holder.timelabel = (TextView) itemView.findViewById(R.id.timeposted);
holder.post_caption = (TextView) itemView.findViewById(R.id.caption);
holder.editcaption = (EditText) itemView.findViewById(R.id.editText1);
itemView.setTag(holder);
}
else{
itemView = convertView;
holder = (ViewHolder) itemView.getTag();
}
I am trying to implement a listview that displays a list of directories. and under each directory is a gridview with associated adapter (shown below) showing a list of image thumbnails (see below image). I have it working great except whenever the list item is off the screen then brought back on screen, the images are reloaded. I am using an asynctask to download the thumbnails and replace the placeholder image for each imageview so it is not acceptable that everytime an item is offscreen, all of its thumbnails are downloaded again. Does anyone have an example of this type of implementation (gridview adapter within a listview adapter) where the imageview (or images) are stored? What is the proper way to do this?
Thanks in advance for your help.
Gallery Adapter
public class GalleryAdapter extends BaseAdapter {
private Context mContext;
ArrayList<GalleryItem> GalleryList;
//MediaAdapter adapter;
public GalleryAdapter(Context c,ArrayList<GalleryItem> l) {
mContext = c;
GalleryList = l;
}
public int getCount() {
return GalleryList.size();
}
public Object getItem(int position) {
return GalleryList.get(position);
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
GalleryViewHolder viewHolder = null;
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(R.layout.gallery_item, parent, false);
viewHolder = new GalleryViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.folder_settings = (ImageView) convertView.findViewById(R.id.folder_settings);
viewHolder.mediaGrid = (GridView) convertView.findViewById(R.id.imagegrid);
viewHolder.gridHolder = (LinearLayout) convertView.findViewById(R.id.gridholder);
convertView.setTag(viewHolder);
}
else{
viewHolder = (GalleryViewHolder) convertView.getTag();
}
viewHolder.title.setText(GalleryList.get(position).getTitle());
//Formatting the gridView to fit the screen dim.
ImageTools mWidth = new ImageTools(mContext);
viewHolder.mediaGrid.setColumnWidth(mWidth.imageSize());
int rows = (int) Math.ceil((GalleryList.get(position).getMedia().size() / mWidth.columnNumber)+1);
LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, mWidth.imageSize()*rows);
viewHolder.gridHolder.setLayoutParams(labelLayoutParams);
viewHolder.mediaGrid.setLayoutParams(labelLayoutParams);
viewHolder.mediaGrid.setMinimumHeight(mWidth.imageSize()*rows);
//Set Adapter for image views
viewHolder.mediaGrid.setAdapter(new MediaAdapter(convertView.getContext(),GalleryList.get(position).getMedia()));
viewHolder.folder_settings.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Dialogs.createListDialog(mContext,"Folder Actions", R.array.gallery_action_array).show();
}
});
viewHolder.mediaGrid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
}
});
return convertView;
}
private class GalleryViewHolder {
private TextView title;
private ArrayList<ImageView> imageList;
private GridView mediaGrid;
private ImageView folder_settings;
private LinearLayout gridHolder;
private int position;
}
}
Media Adapter
public class MediaAdapter extends BaseAdapter {
private Context mContext;
ArrayList<MediaItem> mediaitems;
public MediaAdapter(Context c,ArrayList<MediaItem> l) {
mContext = c;
mediaitems = l;
}
public int getCount() {
return mediaitems.size();
}
public Object getItem(int position) {
return mediaitems.get(position);
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setImageResource(R.drawable.loading);
imageView.setTag(R.integer.path,mediaitems.get(position).getPath().toString());
imageView.setTag(R.integer.fullsize,"false");
imageView.setTag(R.integer.parentpath,mediaitems.get(position).getParentPath().toString());
imageView.setTag(R.integer.index , String.valueOf(position));
try {
new thumbDownload(mContext).execute(imageView);
} catch (DbxException e) {
e.printStackTrace();
}
ImageTools mWidth = new ImageTools(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(mWidth.imageSize(), mWidth.imageSize()));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
//imageView.setImageBitmap(mediaitems.get(position).getBitmap());
return imageView;
}
}
Try with this..may be its silly way, but its worked for me. Just add a line of code inside your method like this for gallery adapter:
public View getView(int position, View convertView, ViewGroup parent) {
GalleryViewHolder viewHolder = null;
// Add this line.
convertView = null;
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(R.layout.gallery_item, parent, false);
viewHolder = new GalleryViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.title);
viewHolder.folder_settings = (ImageView) convertView.findViewById(R.id.folder_settings);
viewHolder.mediaGrid = (GridView) convertView.findViewById(R.id.imagegrid);
viewHolder.gridHolder = (LinearLayout) convertView.findViewById(R.id.gridholder);
convertView.setTag(viewHolder);
}
else{
viewHolder = (GalleryViewHolder) convertView.getTag();
}
// rest of your code
}
You can use StickyGridHeaders to implement your UI and Android-Universal-Image-Loader for flexible asynchronous image loading.
StickyGridHeaders is an Android library that provides a GridView that shows items in sections with headers. By default the section headers stick to the top like the People app in Android 4.x but this can be turned off.
Android-Universal-Image-Loader aims to provide a reusable instrument for asynchronous image loading, caching and displaying.
I ended up Using a HashMap<String,Bitmap> to store the images once they were downloaded. I made the hashMap static in my mediaAdapter so I could add the bitmap from my asynctask when it was downloaded. Then in my media Adapter getView(), I added a if statement to check if the image had already been downloaded. If it had, I used setImageBitmap(myHash.get(key)).
I have listview which contains textview and buttons. When i delete listview item and i try to scroll down, i get exception on this:
BuildQueue eile = countryList.get(position);
Exception:
02-08 19:11:04.279: E/AndroidRuntime(10509): java.lang.IndexOutOfBoundsException: Invalid index 15, size is 15
Seems i do not updating something when i delete item from listview. I think i have problem with ViewHolder, but i do not know what kind of...
My ArrayAdapter code:
public class MyCustomAdapter extends ArrayAdapter<BuildQueue> {
private ArrayList<BuildQueue> countryList;
public MyCustomAdapter(Context context, int textViewResourceId,ArrayList<BuildQueue> countryList) {
super(context, textViewResourceId, countryList);
this.countryList = new ArrayList<BuildQueue>();
this.countryList.addAll(countryList);
}
private class ViewHolder {
TextView code;
TextView field;
Button del;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.queue_buildings, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.code);
holder.field = (TextView) convertView.findViewById(R.id.field_text);
holder.del = (Button) convertView.findViewById(R.id.del_button);
convertView.setTag(holder);
holder.del.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Button del_button = (Button) v;
BuildQueue building = (BuildQueue) del_button.getTag();
countryList.remove(building);
dataAdapter.notifyDataSetChanged();
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
BuildQueue eile = countryList.get(position);
holder.code.setText(" ( Level: " + eile.getOld_level() + " to "+eile.getNew_level()+")");
holder.field.setText(eile.getNameSort());
holder.field.setTag(eile);
holder.del.setText("Delete");
holder.del.setTag(eile);
return convertView;
}
}
You are using a two arrays in your Adapter, but only changing one of them.
Every Adapter uses getCount() to determine how many row should be drawn. ArrayAdapter's getCount() simply asks for the size of the array that you pass to the super constructor here: super(context, textViewResourceId, countryList);. But you are also using a second, local array and when you delete a value from this countryList getCount() has no idea this happened which results in getView() throwing an IndexOutOfBoundsException...
Either extend BaseAdapter, or use ArrrayAdapter's methods like getItem(), add(), and remove() and remove your local data set.
Is it possible to get an item view based on its position in the adapter and not in the visible views in the ListView?
I am aware of functions like getChildAt() and getItemIdAtPosition() however they provide information based on the visible views inside ListView. I am also aware that Android recycles views which means that I can only work with the visible views in the ListView.
My objective is to have a universal identifier for each item since I am using CursorAdapter so I don't have to calculate the item's position relative to the visible items.
Here's how I accomplished this. Within my (custom) adapter class:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflater = context.getLayoutInflater();
view = inflater.inflate(textViewResourceId, parent, false);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.name = (TextView) view.findViewById(R.id.name);
viewHolder.button = (ImageButton) view.findViewById(R.id.button);
viewHolder.button.setOnClickListener
(new View.OnClickListener() {
#Override
public void onClick(View view) {
int position = (int) viewHolder.button.getTag();
Log.d(TAG, "Position is: " +position);
}
});
view.setTag(viewHolder);
viewHolder.button.setTag(items.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).button.setTag(items.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
return view;
}
Essentially the trick is to set and retrieve the position index via the setTag and getTag methods. The items variable refers to the ArrayList containing my custom (adapter) objects.
Also see this tutorial for in-depth examples. Let me know if you need me to clarify anything.
See below code:
public static class ViewHolder
{
public TextView nm;
public TextView tnm;
public TextView tr;
public TextView re;
public TextView membercount;
public TextView membernm;
public TextView email;
public TextView phone;
public ImageView ii;
}
class ImageAdapter extends ArrayAdapter<CoordinatorData>
{
private ArrayList<CoordinatorData> items;
public FoodDriveImageLoader imageLoader;
public ImageAdapter(Context context, int textViewResourceId,ArrayList<CoordinatorData> items)
{
super(context, textViewResourceId, items);
this.items = items;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
ViewHolder holder = null;
if (v == null)
{
try
{
holder=new ViewHolder();
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new FoodDriveImageLoader(FoodDriveModule.this);
v = vi.inflate(R.layout.virtual_food_drive_row, null);
//System.out.println("layout is null.......");
holder.nm = (TextView) v.findViewById(R.id.name);
holder.tnm = (TextView) v.findViewById(R.id.teamname);
holder.tr = (TextView) v.findViewById(R.id.target);
holder.re = (TextView) v.findViewById(R.id.received);
holder.membercount = new TextView(FoodDriveModule.this);
holder.membernm = new TextView(FoodDriveModule.this);
holder.email = new TextView(FoodDriveModule.this);
holder.phone = new TextView(FoodDriveModule.this);
holder.ii = (ImageView) v.findViewById(R.id.icon);
v.setTag(holder);
}
catch(Exception e)
{
System.out.println("Excption Caught"+e);
}
}
else
{
holder=(ViewHolder)v.getTag();
}
CoordinatorData co = items.get(position);
holder.nm.setText(co.getName());
holder.tnm.setText(co.getTeamName());
holder.tr.setText(co.getTarget());
holder.re.setText(co.getReceived());
holder.ii.setTag(co.getImage());
imageLoader.DisplayImage(co.getImage(), FoodDriveModule.this , holder.ii);
if (co != null)
{
}
return v;
}
}
A better option is to identify using the data returned by the CursorAdapter rather than visible views.
For example if your data is in a Array , each data item has a unique index.
Here, Its very short described code, you can simple re-use viewholder pattern to increase listview performance
Write below code in your getview() method
ViewHolder holder = new ViewHolder();
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.skateparklist, null);
holder = new ViewHolder();
holder.headlineView = (TextView) convertView
.findViewById(R.id.textView1);
holder.DistanceView = (TextView) convertView
.findViewById(R.id.textView2);
holder.imgview = (NetworkImageView) convertView
.findViewById(R.id.imgSkatepark);
convertView.setTag(holder); //PLEASE PASS HOLDER AS OBJECT PARAM , CAUSE YOU CAN NOY PASS POSITION IT WILL BE CONFLICT Holder and Integer can not cast
//BECAUSE WE NEED TO REUSE CREATED HOLDER
} else {
holder = (ViewHolder) convertView.getTag();
}
// your controls/UI setup
holder.DistanceView.setText(strDistance);
......
return convertview
Listview lv = (ListView) findViewById(R.id.previewlist);
final BaseAdapter adapter = new PreviewAdapter(this, name, age);
confirm.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
View view = null;
String value;
for (int i = 0; i < adapter.getCount(); i++) {
view = adapter.getView(i, view, lv);
Textview et = (TextView) view.findViewById(R.id.passfare);
value=et.getText().toString();
Toast.makeText(getApplicationContext(), value,
Toast.LENGTH_SHORT).show();
}
}
});