Getting package name in custom spinner - android

I am using a custom spinner library, Material Spinner. I have set adapter to the spinner as I want the font size to be different in the getDropDownView. I have three spinners out of which two just show the packagename. The middle spinner is working properly.
Everything is the same for all three spinners other than the array and the width. So why is the middle spinner. I can't figure out what the issue is.
This is not a duplicate question
One reason mentioned is that the getView method should be overridden. As can be seen below, it has been done. What I did find that in the case of the 1st and 3rd spinner the getView method or the getDropDownView method is not being called. I don't understand why.
getItemCount, getItemId, getItem methods are not needed. But when I had these methods also, the result did not change.
MaterialSpinner msDay = (MaterialSpinner) getActivity().findViewById(R.id.fgenderage_ms_day);
List dayList = Arrays.asList(getResources().getStringArray(R.array.fgenderage_day));
msDay.setItems(new EnglishSpinnerAdapter(getActivity(), dayList));
MaterialSpinner msMonth = (MaterialSpinner) getActivity().findViewById(R.id.fgenderage_ms_month);
List monthList = Arrays.asList(getResources().getStringArray(R.array.fgenderage_month));
msMonth.setAdapter(new EnglishSpinnerAdapter(getActivity(), monthList));
MaterialSpinner msYear = (MaterialSpinner) getActivity().findViewById(R.id.fgenderage_ms_year);
List yearList = Arrays.asList(getResources().getStringArray(R.array.fgenderage_year));
msYear.setItems(new EnglishSpinnerAdapter(getActivity(), yearList));
The adapter:
public class EnglishSpinnerAdapter extends MaterialSpinnerAdapter{
private List list;
private Context ctx;
public EnglishSpinnerAdapter(Context context, List items) {
super(context, items);
ctx = context;
list = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(ctx);
textView.setText(list.get(position).toString());
return textView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(ctx);
textView.setText(list.get(position).toString());
return textView;
}

change this
msDay.setItem(new EnglishSpinnerAdapter(getActivity(), dayList));
to this
msDay.setAdapter(new EnglishSpinnerAdapter(getActivity(), dayList));

Related

Iterating through every item in a ListView - Android

I need my application to apply a strike through to the contents of each item in my ListView based on whether or not the content of each item is marked as checked off or not in my SQLite database. Right now I obtain the text for each item in the list view from a database table, store it in a List, pass that into a ArrayAdapter, and then use that to set my ListView adapter. This is my code:
private ListView taskList = (ListView) view.findViewById(R.id.task_list);
// Get text for each TextView from database
db.getWritableDatabase();
tasks = db.readTasks((int) listId);
// Set up adapter for ListView
adapter = new ArrayAdapter<String>(
view.getContext(),
android.R.layout.simple_expandable_list_item_1,
tasks);
taskList.setAdapter(adapter);
My thought was to iterate through each item in the ListView after it has been set and check to see if the corresponding record in the database had it marked as checked or not, and then act accordingly on the item. I don't know how to iterate over the contents of a ListView however, nor am I certain this is the best way to do this. Does anyone know how to iterate over the contents of a ListView or is there an entirely better way to do this?
Firstly define a Task object with useful properties:
class Task {
public boolean isComplete() {...};
#override String toString() {...};
}
Then make your db method return a list of such objects:
ArrayList<Task> tasks = db.readTasks((int) listId);
Finally, subclass the ArrayAdapter:
private static class TaskAdapter extends ArrayAdapter<Task> {
private ArrayList<Task> mTasks;
TaskAdapter (Context c, ArrayList<Task> list) {
super(c, android.R.layout.simple_spinner_item, list);
mTasks = list;
}
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View v = super.getView(position, convertView, parent);
TextView txt = v.findViewById(android.R.id.text1);
int flags = txt.getPaintFlags();
if (mList.get(position).isComplete()) {
flags = flags | Paint.STRIKE_THRU_TEXT_FLAG;
} else {
flags = flags & ~Paint.STRIKE_THRU_TEXT_FLAG;
}
txt.setPaintFlags(flags);
}
}
You can also do a lot more when you subclass the adapter: eg. create your own view layout (eg. if you wanted a 'tick' graphic instead of a strikethough).
Google for examples of this kind of thing. There are many.

Custom ArrayAdapter without custom item data-type

I try to implement a ListView with specific icon, title and subtitle at each item.
The data of all items is in an ArrayList of objects from following class:
class ItemObject{
String title="";
String subTitle="";
String unit="";
int icon;
int quantity;
int parentID;
int orderInList;
}
ArrayList<ItemObject> listViewData;
Here is the code I used first:
class ExtendedArrayAdapter<String> extends ArrayAdapter<String>{
private Context context;
private String[] items;
public ExtendedArrayAdapter(Context context, String[] items){
super(context,-1,items);
this.context = context;
this.items=items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.lv_item_bg,parent,false);
TextView itemTitle = (TextView)itemView.findViewById(R.id.itemTitle);
TextView itemSubTitle = (TextView)itemView.findViewById(R.id.itemSubTitle);
ImageView itemIcon = (ImageView)itemView.findViewById(R.id.itemIcon);
itemTitle.setText(listViewData.get(position).title);
itemSubTitle.setText(listViewData.get(position).subTitle);
itemIcon.setBackgroundResource(listViewData.get(position).icon);
return itemView;
}
}
But the problem regarding this custom ArrayAdapter is that ExtendedArrayAdapter needs a String[] of items to get the number of ListView items.
Question:
Is it possible to change the ExtendedArrayAdapter class to get directly the length of ListView instead of String[] items?
EDIT1:
In super(), I can use only following set of parameters:
and all need Array<String> or List<String>. So I cannot use my ArrayList of objects here.
Is it possible to change the ExtendedArrayAdapter class to get
directly the length of ListView instead of String[] items?
the length of the ListView in terms of item it is handling, is given from Adapter.getCount(). The answer to your question, if I understand it correctly, is then no. The definition of your Adapter should change like
class ExtendedArrayAdapter extends ArrayAdapter<ItemObject>{
you will have to change the constructor and the type of items as well

Why is the Spinner's interface SpinnerPopup private? Why can't I add my own popup view?

I was looking at a way to answer this question where the OP is trying to limit the number of items displayed in the spinner's dropdown view. It seems that it cannot be done.
The Spinner class has its own private interface called SpinnerPopup which defines how dropdown items can be shown. This is currently based on the spinnerMode allowing for a dropdown or dialog list.
Both options are also implemented inside the Spinner class as private classes: DialogPopup and DropdownPopup. So it seems to me that the only way to customize this to add another popup option would be to copy the spinner source code and create my own version of it.
But if the SpinnerPopup interface were public, it seems like it would be easy to just:
Create my own popup implementing SpinnerPopup; and
Create my own spinner extending the original one where I override the constructor Spinner(Context context, AttributeSet attrs, int defStyle, int mode) to handle my popup.
Does anyone have any idea (or guess) why this is not the case? Or am I missing a simpler solution here?
Thanks!
I need set my own view to the dropdown, so this was what I did:
public class SpinnerAdapter_Tabela_Preco extends ArrayAdapter<Tabela_Preco>{
// Your sent context
private Context context;
private List<Tabela_Preco> list_tabela_preco;
public SpinnerAdapter_Tabela_Preco(Context context, int textViewResourceId, List<Tabela_Preco> values) {
super(context, textViewResourceId, values);
this.context = context;
this.list_tabela_preco = values;
}
public int getCount(){
return list_tabela_preco.size();
}
public Tabela_Preco getItem(int position){
return list_tabela_preco.get(position);
}
public long getItemId(int position){
return position;
}
// And the "magic" goes here
// This is for the "passive" state of the spinner
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Tabela_Preco t_p = getItem(position);
// I created a dynamic TextView here, but you can reference your own custom layout for each spinner item
TextView label = new TextView(context);
label.setTextColor(Color.BLACK);
label.setTypeface(null, Typeface.BOLD);
// Then you can get the current item using the values array (Users array) and the current position
// You can NOW reference each method you has created in your bean object (User class)
label.setText(t_p.toString());
// And finally return your dynamic (or custom) view for each spinner item
return label;
}
// And here is when the "chooser" is popped up
// Normally is the same view, but you can customize it if you want
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
Tabela_Preco t_p = getItem(position);
TextView label = new TextView(context);
label.setTextColor(Color.BLACK);
label.setBackgroundColor(Color.WHITE);
label.setMinimumHeight(50);
label.setGravity(Gravity.CENTER_VERTICAL);
label.setTextSize(18);
label.setText(t_p.toString());
return label;
}
}
And I use with this:
final SpinnerAdapter_Tabela_Preco adapter = new SpinnerAdapter_Tabela_Preco(Consulta_Produto.this, android.R.layout.simple_spinner_item, lista_tabela_preco);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spn_tabela_preco.setAdapter(adapter);
I hope this could help you.

How to findViewId the TextView that is done programatically

I have a list of textView that is programmed dynamically...
GridView layout = (GridView) context.findViewById(R.id.linearLayout1);
PrizeAdapter adapter = new PrizeAdapter(context, 0, 0, game.getPrizeList());
layout.setAdapter(adapter);
Adapter Class:
public class PrizeAdapter extends ArrayAdapter<String> {
private List<String> objects;
public PrizeAdapter(Context context, int resource, int textViewResourceId,
List<String> objects) {
super(context, resource, textViewResourceId, objects);
this.objects = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView text = new TextView(getContext());
text.setId(position);
text.setText(objects.get(position));
text.setTextSize(12);
text.setPadding(0, 5, 0, 5);
text.setTextColor(Color.WHITE);
text.setBackgroundColor(Color.GRAY);
text.setGravity(Gravity.CENTER | Gravity.BOTTOM);
return text;
}
}
Supposedly, I have created a 10 TextView. How can i get the particular textView so i can color it differently.
I tried this
GridView layout = (GridView) context.findViewById(R.id.linearLayout1);
TextView view = (TextView) layout.findViewById(1);
view.setBackgroundColor(Color.YELLOW);
view.setTextColor(Color.RED);
But it doesn't work and just encountered a nullpointer exception.
Please help.
The reason for such behavior is you are doing it too early.
i.e even before the view are created with id 1 you are trying to access them.
So what is happening is, you ask adapter to inflate view and adapter takes control checking what is visible and what should be displayed.
and immediately after if ( before view are populated) you call findviewbyID(1) so this view is still not created hence you get null pointer.
The code will work if we try to use a button to do the task after grid is populated.
final GridView layout = (GridView) findViewById(R.id.linearLayout1);
PrizeAdapter adapter = new PrizeAdapter(this, 0, 0, objects2);
layout.setAdapter(adapter);
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView view = (TextView) layout.findViewById(1);
view.setBackgroundColor(Color.YELLOW);
view.setTextColor(Color.RED);
// TODO Auto-generated method stub
}
});
So 2 solution
1) delayed handler post for changing color.
2) create a custom callback interface which will give you back result like view 1 loaded.
Use ViewGroup.getChildAt(position), which will return you the view at that position. Then Typecast it to TextView(as you are setting the TextView as direct item View) to set color.
One more thing you cannot use findViewById() when you are creating objects dynamically unless you set ID for the object.

how can i use android ListView to display fields in an object?

I am trying to construct a ListActivity that uses a listview to display a list of friends and their associated status (ie single, in a relationship).
So far, I have an ArrayAdapter set like so:
Friend[] friendList = new Friend[] {
new Friend("john doe", "single"),
new Friend("jane doe", "married")
};
setListAdapter(new ArrayAdapter<Friend>(this, R.layout.portal_listview, friendList));
I would like each item in the listview to display as such:
1name: john doe
status: single
2name: jane doe
status: married
Create you own CustomArrayAdapter which extends ArrayAdapter and overwrite the View getView(int position, View convertView, ViewGroup parent) method
I could be something like this
public class FriendAdapter extends ArrayAdapter<Friend>{
private Context context;
private int resource;
private ArrayList<Friend> friends;
public FriendAdapter(Context context, int resource, ArrayList<Friend> friends) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
this.friends = friends;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
if (view == null){
LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(your_list_item_resource, null);
}
Friend friend = friends.get(position);
view.setId(position);
if (friend != null){
TextView name = (TextView) view.findViewById(R.id.friendName);
name.setText(friend.getName());
TextView status = (TextView) view.findViewById(R.id.friendStatus);
status.setText(friend.getStatus());
}
return view;
}
Hope this can help you.
In the xml row file, you can add a composite object, like a LinearLayout
and inside that you could include more than one textview, or a combination etc.
I guess the linearlayout would be unnecessary if the individual items within the list are displayed vertically, but you can try.
You need to override getView in the ArrayAdapter class. In that method, inflate your R.layout.portal_listview instance and fill it with whatever you want.
That xml layout should be some layout form that includes a TextView for the two things you want to display.
Easiest would be a linear layout, set to vertical orientation, with 2 TextViews in it, stacked.

Categories

Resources