I'm looking for an effective and reusable way of reusing lists of data in slightly different contexts.
What I have is a list like the following:
[Bitmap] PlayerName
[Bitmap] PlayerName
...
These are stored as ArrayLists that I get from Cursors and are parcelable so I can move them around as required.
The issue I have is that I want to re-use the Image and name but change info within the line.
What I mean is this:
When I show the players in the first list, I have a remove button that removes that player from the whole game.
In another list I also use a remove button but that's to remove them from a specific instance of a game.
In both these instances I've got a Removebutton with the list, I use lazy hackery when I construct the ListaAapter to choose what the button does. The listitems themselves have no listener, just the button.
I now want to reuse the player list again, but have the whole items clickable (i.e. use the OnItemClickListener or some such) and then place a number next to them (in the order they were clicked).
I imagine I could add a TextView under the Remove box and wire it into the same thing and make the TextView and the Button visible as required but that seems like a pretty bad way to manage it.
How should I separate the presentation from the data in this instance?
Potential solutions
1.
As per a suggestion on using layouts, I have a constructor like this:
public PlayerListAdapter(Context context, ArrayList<Player> players, GameInstance gameInstance) {
super(context, R.layout.row_player_empty, players);
this.context = context;
this.players = players;
this.gameInstance = gameInstance;
}
Would I add an int for layout to that constructor and then change my getView and onClick methods to use the layout to drive the different data sources?
2.
Another solution I've looked at is 'merging' layouts. Here I create a base 'player' and then for each set of additional UI elements I wrap the base into the additional elements as a new layout. This at least means I'm re-using the font/size/margins etc.
I'd probably rather overlay the elements a bit more dynamically but at least If I change the base style i'm doing it once rather than 3 times.
You can manage both list with different xml for it.
From fragment/activity, you can passs which kind of list view you are looking and on depneds on that, your xml out of 2 layout will inflate and you can set values.
In first case, you need just delete button clickable, so you can set listener on that only, in second case you need entire button clickable, so you can set onClickListner when you set that kind of list view xml.
As you have 2 cases:
in case 1, you should pass any boolean or enum kind value in constructor, so you can identify which kind of xml, I need to populate
And in getView() before inflating view, you should compare that value and depends on that, you should populate xml, like:
getView(){
if(case1){
View view = mInflater.inflate(R.layout.case_one_layout, null);
//set all values and listener on delete button as your require.
}else if(case2){
View view = mInflater.inflate(R.layout.case_two_layout, null);
//here you can set listener on entire row as onItemclick from fragment.
}
}
You can also manage with switch or other way as you like.
Related
I'm trying to create a timeline using recycler view. I need to dynamically add and remove 2 different types of viewholder at the runtime (Note: not the data, "ViewHolder!").
Each viewholder represent a different set of data and layout.
Help me to solve this.
One solve would be to add both(all) smaller items to one item like this.
<OuterLayout
android:style="#style/yourStyle">
<InnerLayout
android:style="#style/innerStyle1"
...interior elements i.e. text views/buttons/>
<InnerLayout2
android:style="#style/innerStyle2"
...interior elements i.e. text views/buttons/>
</OuterLayout>
In your java code then you simply need a function like this
public static void minimize(LinearLayout layout){
LinearLayout.LayoutParams size = new LinearLayout.LayoutParams(0,0);
layout.setLayoutParams(size);
}
All you would need to do from the Adapter is to call minimize on the one you don't want. You will also need a corresponding expand() function because of how a RecyclerView recycles the views. You may have to change the function above to work for your layout.
First I have build a simple android application which had only five optios to select. For this purpose I used five Buttons on main Activity. Now I have more than twenty buttons in a ScrollView to select. What is the best way to represent this kind of application (using buttons in a ScrollView? using TabHost? or with some other widget?)
The app look like this now:
Grid View or List View or Recycler View
the Adapter automatically will add buttons with the names you want, something that I did for my upcoming app.
I made a java class called data which has 'data` for my app.
it has an array of images for my GridView.
SO:
Make a class called data
Add a public final static String[] myArray array of your names, or data
Now, whenever you want to access them, use data.myArray
If you want to access one item ,use data.myArray[itemIndex]
Don't forget, indexes are zero based, not 1
Put your button inside a viewHolder class
find the id of the button in the getView if convertView is null & set the holder as a tag
NOTE : after finding the ID of the button, just leave it don't do anything or edit the text, continue reading please.
Use that array with your custom adapter
as
gridView.setAdapter(new myCustomAdapter(parameter1, parameter2,data.myArray);
use this , I just made it yesterday, added array of buttons feature now. You can just learn it or use it or commit changes.
NOTE :
You can make an array of listeners just like any primitive data type, View.OnClickListener[] and name it, initialize it.
Use grid view. it will be easy to show multiple buttons on screen using grid view.
What would be a way of doing this, or the best way to do this? For example I would want to split mListMain, into mList1, mList2, mList3 and be able to set separate Long Click listeners, listitem listeners and context menus for each. Something like mList1.setlistitemclicklistener, registercontextmenu.(mList2)...
The reason I want to know how to do this, if it's even possible, is that I've merged multiple ListView's arrays using mergeAdapter from CommonGuy, but now since it's all one list, none of the things I set for the separate lists remain, like context menus and onitemclicklisteners.
none of the things I set for the separate lists remain, like context menus and onitemclicklisteners
You are welcome to set up item-click and item-long-click listeners for the ListView. However, you will have to interpret the position properly, to determine what sub-list the position pertains to, so you can decide what to do on those events.
You can add list views as part of views of list view
so there is parent list view whose adaptor's getView returns child list view .
This will you can multiple list view part of one parent list view
If you are creating a very dynamic list, say, where every row can have a different set of input types plus optional buttons, and the list length is based on another dynamic value, is it better to do this in a list adapter or creating a custom view in a scroll window?
After struggling with list adapters for quite a while now something finally occurred to me- this seems dumb. It seems like I am going through a lot of work keeping track of what spinner is set to what value, which row was clicked and so forth.
For example, say you are showing something like a contacts screen with various details that can be entered about a contact. Some rows will have text inputs (name, address etc), some will have spinners (ie. state, group), some will have checkboxes (like 'favorite' or something). Also, there is an 'add' button that allows you to add another field to edit. Is it worth making this in a list adapter or is it better to populate a custom view, and if the "add" button is clicked, we re-create the custom view, adding a view of the type they want to add?
I hope this is clear.
ListViews (and List Adapters) are meant for data that is to be displayed in mainly similar views. For your example, it is much easier and more natural to have a predefined layout file with the screen and use view visibility so select which views are to be shown. If you need to add views to the screen you can do this dynamically by using findViewById on the layout and then using it's addView method.
Let me know if you need more clarification or sample code...
I have created a compound control that I am reusing in multiple activities. This control contains a bunch of TextViews and Buttons, and most importantly a ListView. I define the XML in a layout file and in the constructor to this compound control, I inflate the XML as such:
String service = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(service);
inflater.inflate(R.layout.map_menu, this, true);
The layout XML contains a ListView, and also in the constructor this compound control will handle setting up the adapter (my adapter extends ArrayAdapter) and array for it, like so:
ListView tableOfContentsList = (ListView) findViewById(R.id.tocListView);
_layerAdapter = new LayerAdapter(context, R.layout.toc_layer_item, _layers);
tableOfContentsList.setAdapter(_layerAdapter);
This compound control is used in two activites - one of these activities calls another. No relation between the two activities is intended.
Here is my problem. When the compound control is created in the initial activity, the above code is called to set the adapter of this control. Then, when the second activity is created and navigated to, the constructor is called again on this second instance of the control. This seems to have a side effect on the first control located in the initial activity. The second control seems to overwrite parts of the adapter from the first control - because basically the first adapter will not be functional once the constructor to the second control is called.
It is my guess that since I am referencing the resource ID of the ListView in both controls, Android is removing the adapter from the first ListView when the second ListView is created - because it sees both ListViews as having the same resource ID? Is this possible?
I have had trouble before in this exact same case - where multiple compound controls are used in different activities (and multiple times in a single activity) - and the problem was due to inflating from XML layout. My solution to that prior problem was to get rid of the inflating from layout, and instead creating the objects through code. This was acceptable because those compound controls were much simpler and contained only two views - however I feel in the above ListView case, where my compound control has at least ten views in it, it is not an acceptable solution to define each view in code. I need the layout XML.
Has anyone ever experienced this sort of clashing behavior when using custom compound controls that are inflated from XML, and re-used in multiple instances?
From my understanding Android should create a new instance of the widgets each time you inflate the xml. Do you have any static members in you compound widget class?