I want to have custom spinner that has image and a textView in drop down list so I created different layout and inflated it, and its working fine but for layout of spinner before pressing spinner I just want to have a text like "choose from list" but when I inflating with
android.R.layout.simple_spinner_item
for getView, I'm just getting a drop down arrow and not text
How to populate layout in getView, do i have to create new dataset? different from dropdown? here is my code: I'm implementing SpinnerAdapter for custom adapter
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(R.layout.spinner_item, parent, false);
ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
TextView tv = (TextView) convertView.findViewById(R.id.tv1);
iv.setImageResource(R.drawable.flower);
tv.setText(itemList[position]);
return convertView;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(android.R.layout.simple_spinner_item,
parent, false);
return convertView;
}
Declare the ViewHolder Class inside your spinner adapter
private static class ViewHolder{
TextView tv_itemname;
}
And modify your getView() method like this:
public View getView(final int position, View convertView, ViewGroup parent) {
View vi = convertView;
SpinnerListAdapter.ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.spinner_item_row, null);
holder = new SpinnerListAdapter.ViewHolder();
holder.tv_itemname = (TextView) vi.findViewById(R.id.tv_itemname);
vi.setTag( holder );
}
else
{
holder = (SpinnerListAdapter.ViewHolder) vi.getTag();
}
if (position == 0)
{
holder.tv_itemname.setText("Choose one of the following category");
}else{
holder.tv_itemname.setText(itemList[position]);
}
return vi;
}
text1 is the identifier for TextView in android.R.layout.simple_spinner_item
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = inflater.inflate(android.R.layout.simple_spinner_item,
parent, false);
TextView text1 = (TextView) convertView.findViewById(android.R.id.text1);
text1.setText(itemList[position]);
return convertView;
}
Related
I am just adapting my custom adapter code with ViewHolder so that i can optimize my list view with a recycler, but i am not sure if i do it right.
My view holder class:
public class ViewHolderTask {
int positionHolder;
TextView nameHolder;
TextView timeHolder;
TextView sessionHolder;
TextView dateHolder;
FloatingActionButton mFabTaskHolder;
public ViewHolderTask(View v, int position) {
this.positionHolder = position;
this.nameHolder = v.findViewById(R.id.taskNameText);
this.timeHolder = v.findViewById(R.id.timeTextView);
this.sessionHolder = v.findViewById(R.id.textViewSession);
this.dateHolder = v.findViewById(R.id.dateTextView);
this.mFabTaskHolder = v.findViewById(R.id.myFabTask);
}
My custom adapter class:
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
ViewHolderTask holder;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE );
convertView = inflater.inflate(R.layout.task_row, parent, false);
holder = new ViewHolderTask(convertView, position);
convertView.setTag(holder);
}else{
holder = (ViewHolderTask) convertView.getTag();
}
Task task = taskArrayList.get(position);
//set the configurations
holder.getTimeHolder().setText(getTimeString(task.getTime()));
holder.getNameHolder().setText(task.getName());
holder.getDateHolder().setText(getDateString(task.getDate()));
holder.getSessionHolder().setText(getSessionString(task.getSession()));
//Set the FAB listener
addFabListener(holder.getmFabTaskHolder(), position);
//set the clicked background
if(TaskActivity.getIsClicked() && TaskActivity.getPositionClicked()-1 == position){
convertView.setBackgroundResource(R.color.backgroundSelectedItem);
}
return convertView;
}
Do I use it right?
Seems to be fine for me other than this portion of the code
//set the clicked background
if(TaskActivity.getIsClicked() && TaskActivity.getPositionClicked()-1 == position){
convertView.setBackgroundResource(R.color.backgroundSelectedItem);
}
You might need to reset the background resource back to default for the item which is not clicked. maybe you have to add "else" part to the "if"
In ImageView, my images are being shuffled but not the text. This is my getView() method:
public View getView(int position, View convertView, ViewGroup parent) {
View v;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mainActivity.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
v = inflater.inflate(R.layout.item_people, parent, false);
} else {
v = (View) convertView;
}
TextView textView = (TextView) v.findViewById(R.id.name);
ImageView imageView = (ImageView) v.findViewById(R.id.image);
if (list.get(position).getClass() == SearchData.Video.class) {
SearchData.Video video = (SearchData.Video) list.get(position);
textView.setText(video.getVideoName());
if (video.getCoverPicture().length > 0)
imageView.setBackground(mainActivity.Base64toImage(video.getCoverPicture()[0].getImg()));
} else if (list.get(position).getClass() == SearchData.Actor.class) {
SearchData.Actor actor = (SearchData.Actor) list.get(position);
textView.setText(actor.getFirstName());
if (actor.getPicture().length > 0)
imageView.setBackground(mainActivity.Base64toImage(actor.getPicture()[0].getImg()));
}
return v;
}
I am setting image and text of actors. When I scroll down then up the images have shuffled, but not text. Why?
Did you tried the same with ViewHolder
Normally when ever getView() method is called, the gridview/ listview will automatically notified as a change, So that is the reason for your image shuffling s / changing in your gridview.
So, try to implement your Gridview with ViewHolder pattern and avoid those shuffling s / re-orderings
here is the sample code for view holder pattern implementation.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItem viewHolder;
// The convertView argument is essentially a "ScrapView" as described is Lucas post
// http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
// It will have a non-null value when ListView is asking you recycle the row layout.
// So, when convertView is not null, you should simply update its contents instead of inflating a new row layout.
if(convertView==null){
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(layoutResourceId, parent, false);
// well set up the ViewHolder
viewHolder = new ViewHolderItem();
viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);
// store the holder with the view.
convertView.setTag(viewHolder);
}else{
// we've just avoided calling findViewById() on resource everytime
// just use the viewHolder
viewHolder = (ViewHolderItem) convertView.getTag();
}
// object item based on the position
ObjectItem objectItem = data[position];
// assign values if the object is not null
if(objectItem != null) {
// get the TextView from the ViewHolder and then set the text (item name) and tag (item ID) values
viewHolder.textViewItem.setText(objectItem.itemName);
viewHolder.textViewItem.setTag(objectItem.itemId);
}
return convertView;
}
your ViewHodler should be like this
// ViewHolder.
// caches our TextView
static class ViewHolderItem {
TextView textViewItem;
}
This is not the exactly same to your question, but you can edit the above logic for your way.
Hope it Helps :)
I am a beginner. And I've tried a lot but I don't know how I can do this:
I have an ArrayAdapter. That displays all items and if position == 3 it should display also a label.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView;
if (position == 3){
rowView = inflater.inflate(R.layout.event_date, parent, false);
// set text of label ...
// now I want to display also the normal item
} else {
rowView = inflater.inflate(R.layout.events_list, parent, false);
// set text of item ...
}
return rowView;
}
It displays the label but I don't know how I can also show the normal item if it shows the label. How can I do this?
Try using a new layout which would contains both the event_date and events_lists
Something like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView;
if (position == 3){
rowView = inflater.inflate(R.layout.event_date_plus_events_list, parent, false);
// set text of label ...
} else {
rowView = inflater.inflate(R.layout.events_list, parent, false);
}
// set text of item ...
return rowView;
}
I have a gridview in Android which is populated by a custom view which inherits from imagebuttons.
What I would like to do is modify the size of the imagebuttons inside the gridview as well as their padding between cells.
Here is my getView() code. I've tried using layouts but can't because I don't have access to the parent view.
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (image == null)
image = BitmapFactory.decodeResource(context.getResources(), R.drawable.dollar);
ExpenseIcon ic = new ExpenseIcon(context);
ic.setImageBitmap(image);
return ic;
}
How do I do that?
You can set the with with setColumnWidth(int) or set the column count by calling setNumColumns(int) depending on what you extactly trying. By the way you can also set that values by xml (android:columnWidth and android:numColumns).
For the spacing you can use android:horizontalSpacing or setHorizontalSpacing(int) and android:verticalSpacing or setVerticalSpacing(int).
For controling the highe you need to change your getView function:
public YourConstructor() {
// inflater should be a private member variable
inflater = (LayoutInflater)context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// other code...
}
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
// create new one and put it into convertView. e.g.:
convertView = new ExpenseIcon(context);
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(HEIGHT,WIDTH);
convertView.setLayoutParams(lp);
}
// set the image to the currient convertView. e.g.:
((ExpenseIcon)convertView).setImageBitmap(image);
return convertView;
}
Create an XML and inflate.I gave sample to use in getview...Set imagesize in the layout..
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.grid_item, null);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.grid_item_image);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.image.setImageResource(list.get(position).getIconid());
return convertView;
}
static class ViewHolder {
ImageView image;
}
I have made my own CustomArrayAdapter to show list of Brazilian Restaurants. I have overidden the GetView method to make my own custom view.
private class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context context, int resource, int textViewResourceId,
String[] strings) {
super(context, resource, textViewResourceId, strings);
// TODO Auto-generated constructor stub
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.list_item, parent,false);
String [] items= getResources().getStringArray(R.array.locations_array);
TextView tv= (TextView) row.findViewById(R.id.textView1);
ImageView iv = (ImageView) row.findViewById(R.id.imageView1);
tv.setText(items[position]);
iv.setImageResource(R.drawable.brazil);
return row;
}
}
Currently this new GetView class is pulling in a text string from a resource xml file and putting it into the list item.
If I wanted to incorporate an array of extra data generated within the app, I assume that I don't do the array generating in the GetView class as this will be recreated each time a new row is made.
Where do I put the code to make the array, and how do I call this data into the GetView code above?
It's worth pointing out that for better performance you should be making use of the convertView variable passed into the getView() method.
The use of convertView allows you to re-use list item views instead of creating new ones which has a heavy performance hit. If you have a large data set or value performance in your app, you would do well to check out the documentation for getView()
Your code would then look something more like this:
...
//it's also worth moving these methods to your constructor so they aren't called every time getView() for better performance
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
String [] items= getResources().getStringArray(R.array.locations_array);
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
convertView = inflater.inflate(R.layout.list_item, parent, false);
TextView tv= (TextView) convertView.findViewById(R.id.textView1);
ImageView iv = (ImageView) convertView.findViewById(R.id.imageView1);
tv.setText(items[position]);
iv.setImageResource(R.drawable.brazil);
return row;
}
...
Building on #CodeDownZero's answer, I highly recommend you adopt the ViewHolder pattern, and definitely recycle your listviews (using convertview).
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(textViewResourceId, parent, false);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.tv1 = (TextView) view.findViewById(R.id.textView1);
viewHolder.tv2 = (TextView) view.findViewById(R.id.textView2);
view.setTag(viewHolder);
} else {
view = convertView;
}
ViewHolder holder = (ViewHolder) view.getTag();
MyDataClass data = this.getItem(position);
holder.tv1.setText(data.street);
holder.tv2.setText(data.name);
return view;
}
...
private class ViewHolder {
private TextView tv1;
private TextView tv2;
}
You can base an ArrayAdapter on a custom class instead of string. Here is an example:
public class MyDataClass {
public String street;
public String name;
}
private class MyAdapter extends ArrayAdapter<MyDataClass> {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.list_item, parent,false);
TextView tv1= (TextView) row.findViewById(R.id.textView1);
TextView tv2= (TextView) row.findViewById(R.id.textView2);
MyDataClass data = this.getItem(position);
tv1.setText(data.street);
tv2.setText(data.name);
return row;
}
}
To populate the Adapter with data you can use this snippet in the OnCreate method of the Activity:
..
MyAdapter adapter = new MyAdapter();
MyDataClass lData = new MyDataClass(); // here was a mistake
lData.name = "MyName";
lData.street = "MyRoad";
adapter.Add(lData);
..
ListView.Adapter=adapter; // where Listview is the Listview