I'm trying to display high scores for a game I'm creating, with two columns, one for their name, and the other for the amount of moves it took them to complete the game.
Currently it is all stored in a SQLiteDatabase and presented in a list view, where it appears as one column in the format
name,moves
But I'd like to get the moves on the opposite of the screen, would this require multiple list views or would it require editing of the one list view, or its adapter?
The code currently used is:
datasource = new HighScoreDataSource(this);
datasource.open(); //Open the connection
List<HighScore> values = datasource.getAllHighScores(); //Retrieve all the data
//Using a simple cursor adapted to show the elements
ArrayAdapter<HighScore> adapter = new ArrayAdapter<HighScore>(this, android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
Make a row layout with two TextViews placed the way you want and implement a simple custom ArrayAdapter:
public class CustomAdapter extends ArrayAdapter<HighScore> {
private LayoutInflater inflater;
public CustomAdapter(Context context, int textViewResourceId,
List<HighScore> objects) {
super(context, textViewResourceId, objects);
inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.new_row_layout, parent, false);
}
HighScore item = getItem(position);
TextView name = (TextView) findViewById(R.id.name_id_textview);
name.setText(/*get the name from the item HighScore object*/);
TextView moves = (TextView) findViewById(R.id.moves_id_textview);
moves.setText(/*get the moves from the item HighScore object*/);
return convertView;
}
}
Another option is to break your List<HighScore> values in a List of HashMaps(containing two entries, one for name and one for moves) and use a SimpleAdapter(with the row layout above).
Related
I want to create a scrollable list of progress bars. The number of progress bars and the content of each progress bar is decided dynamic and decided at run time.
Is it possible to put create and put progress bars in a ListView? I couldn't find any relevant resources on the internet and hence wanted to confirm if this is even possible in the current android framework.
Yes it is possible, you have to create a custom listView and can add items dynamically whenever you want to add
create a layout that will contain your listView
<ListView
android:id="#+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
create an item layout which will represent your single item of the listView and create a listViewAdapter that will assign your values each of your item of the list
public class ListAdapter extends ArrayAdapter{
private final Context context;
private int layoutResourceID;
private ArrayList<YourDataModel> objects;
public ListAdapter(Context context, int layoutResourceID, ArrayList<YourDataModel> objects) {
super(context, layoutResourceID, objects);
this.context = context;
this.layoutResourceID = layoutResourceID;
this.objects = objects;
}
#Override
public View getView(int position, final View convertView, ViewGroup parent) {
View row = convertView;
final ListHolder listHolder;
if(row == null) {
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceID, parent, false);
itemProgressBar = (ProgressBar) row.findViewById(R.id.item_progressbar);
row.setTag(listHolder);
} else {
listHolder = (ListHolder) row.getTag();
}
final DataCategory list = objects.get(position); // get your data object
// assign values to your items of listView
return row;
}
class ListHolder {
ProgressBar itemProgressBar;
}
}
in the above code YourDataModel your java class containing your data
and last in your main set all the things to make it work
ListAdapterHome listAdapter = new ListAdapter(YourActivity.this,
R.layout.item, ArrayListOfYourDataModel); // pass the arrayList of your dataModel there
ListView listView = (ListView) view.findViewById(R.id.listView);
listView.setAdapter(listAdapterHome);
It is possible. You would have to write your own ListAdapter (i would recommend overwriting SimpleArrayAdapter, but it depends on your Data) and overwrite the getView Method to generate Views that contain a ProgressBar.
Check this question: Custom Adapter for List View
FYI: The ListAdapter is the class that generates the Views of the ListView and assigns their values. Usually if you generate a SimpleArrayAdapter you pass the Layout you want it to create. That works if you only want to set some text in the layout. However to work with a View as specific as a ProgressBar you would have to create your own ListAdapter to handle that specific view.
I need to display a list of A objects (think List<A>). A has the following structure:
class A {
List<B> bList;
List<C> cList;
}
All three lists can be of arbitrary length. bList and cList should be displayed in their entire length in each row of the list of As. Each list is backed by a SQLite cursor. It's a sort of calendar view. The following image illustrates the idea:
Now, I'm wondering what's the best way to achieve this "in the Android way". I tried multiple things:
ListView for A with nested ListViews for B and C: Not recommended, hard to disable the scrolling behaviour of B and C.
ListView for A with LinearLayout for B and C and programmatically adding child views to the LinearLayouts in the Adapter: I have to manage Cursor updates for B and C and adjust the height of the rows myself, lots of view management code in the Adapter where it does not belong.
Composing everything of nested LinearLayouts: Same problem as 2, even more Cursors to deal with.
Maybe there's a different way where I can fully take advantage of existing functionality?
I already had a look at similar questions on StackOverflow. The top two suggestions seem to be:
Spread data over multiple Activities/Fragments: Considered, not an option because not user friendly (in this case).
Use ExpandableListView: Does not seem to be applicable to the data structure, the list of Bs and Cs should be visible from the beginning.
To implement this type of view you need to implement two things.
ListView listView;
IArrayAdapter iArrayAdapter;
Initialize listView with id provided in xml.
Activity.this.runOnUiThread(new Runnable() {
public void run() {
iArrayAdapter = new IArrayAdapter(Activity.this,
R.layout.list_item, "list of items group it from Bean");
listView.setAdapter(iArrayAdapter);
iArrayAdapter.notifyDataSetChanged();
}
});
list_item is another layout which contaion type of display you need to display in list.
IArrayAdapter is class extending ArrayAdapter
public class IArrayAdapter extends ArrayAdapter<IBean> {
private final Activity context;
private final ArrayList<IBean> iBeans;
private int resourceId;
public InboxArrayAdapter(Activity context, int resourceId,
ArrayList<IBean> iBeans) {
super(context, resourceId, inboxBeans);
this.context = context;
this.iBeans = iBeans;
this.resourceId = resourceId;
}
/*
* TO update View
*
* #see android.widget.ArrayAdapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = layoutInflater.inflate(resourceId, null);
final IBean iBean = iBeans.get(position);
final ImageView imageView = (ImageView) rowView
.findViewById(R.id.message);
final TextView rowTxt = (TextView) rowView
.findViewById(R.id.senderName);
final TextView rowTxt1 = (TextView) rowView
.findViewById(R.id.senderMessage);
final TextView rowTxt2 = (TextView) rowView
.findViewById(R.id.senderTime);
final CheckBox check = (CheckBox) rowView.findViewById(R.id.check);
.....set text here.....
return rowView;
}
}
imageView, rowtext, etc are part of layout list_item
ANd IBean is java bean class contain your 5 iTem in a list.
Any item you don't want left it blank.
I have a layout defined with some buttons, and a ListView widget. I also have a layout xml defined for each row in the ListView, with 2 TextViews. I also have data in the format List<String[]> where the String[] is populated with 3 items. I want to display the data in the ListView, with 2 of the 3 items from the String array (contained in each element of the list) assigned to one of the TextView rows in the ListView layout.
I can get a ListView, using one of the default views, to display the full list of just a single item in the array, by breaking it down into a single array of values, and using ArrayAdapter<String>, but I dont know how to do it for multiple rows in the ListView layout.
Would much appreciate any help.
Also, in addition, if the data in the original List<String[]> list should change, how can I refresh the ListView widget?
Thanks for any advice.
You should create your own extension of the ArrayAdapter:
class MyAdapter extends ArrayAdapter<String[]>{
public MyAdapter(Context context, int textViewResourceId, ArrayList<String[]> objects) {
super(context, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if( convertView== null ) convertView = getLayoutInflater().inflate(R.layout.your_layout, null);
String[] strings = getItem(position);
TextView line1 = (TextView)convertView.findViewById(R.id.line1);
line1.setText(strings[0])
TextView line2 = (TextView)convertView.findViewById(R.id.line2);
line2.setText(strings[0])
//...
return convertView;
}
}
To refresh your list, call the adapters notifyDataSetChanged() method.
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.
Hi I want to achieve the following result in my ListActivity:
First item, descritpion
Second item, description
...
where Name and description come from
Cursor c = db.rawQuery(...);
I used a SimpleCursorAdapter and I had no problems. Then I decided to make some modification to data that I have in cursor before displaying it. I wanted to have a internal counter that would increment every time cursor adapter dislays a new view. That's why I decided to implement my own CustomCursorAdapter extending SimpleCursorAdapter:
public class TrainingsListCursorAdapter extends SimpleCursorAdapter{
private Context context;
private int layout;
int list_item_order_number = 1;
public TrainingsListCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.layout = layout;
}//contructor
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent){
Cursor c = getCursor();
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
String durationCol = c.getString(c.getColumnIndex("duration"));
if(durationCol != null){
durationCol = minutesForSeconds(durationCol);
}
TextView textViewDuration = (TextView) v.findViewById(R.id.duration);
TextView order_number = (TextView) v.findViewById(R.id.list_item_num);
if(order_number != null){
order_number.setText(String.valueOf(list_item_order_number));
}
if(textViewDuration != null){
textViewDuration.setText(durationCol);
}
list_item_order_number++;
return v;
}
I have a member variable _list_item_order_number_ that is incremented by one every time a view/row is drawn (by calling newView() method). This number is displayed in every view/list item and it corresponds to list item order...
The problem I have is that when I'm rotating the screen this number doesn't correspond to list items anymore. For example my 3rd item has value 1 and so on...
I guess this has something to do with the order Android is drawing the views. If I scroll the list to, let's say, the middle and then rotate, these numbers are all mixed like this:
First Item
Second item
Third item