I was wondering if it is possible to add subscript values to listview using a custom adapter. My adapter is expecting two List<String> and I'm using this method to populate my ListView. I looked around and a lot of people are recommending the
((TextView)findViewById(R.id.text)).setText(Html.fromHtml("X<sup>2</sup>"));
...but, I do not want the subscript applied to any additional list item that I add. I would only like it added to specific items/instance.
Fields.add("My Sample\nMy Sample\nMy Sample");
Values.add("Value\nValue\nValue");
For example I'd like to be able to pick and choose when it is applied:
Is this possible?
Rows in list view are associated with data in the adapter. To control the content of each row like applying subscript, you need to add necessary information in the data. So you cannot do it if your adapter uses solely List<String>. But if you change it to say a list of Item where Item is
class Item {
String title;
String subtitle;
}
and use List<Item> instead in the adapter. You can apply a subscript given subtitle is null or not in the adapter's getView
class MyAdapter extends ArrayAdapter<Item>{
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// assuming proper view holder pattern is applied here
Item = getItem(position);
if (item.subtitle != null){
//apply subscript state
}else{
//un-apply subscript state
}
return view;
}
}
Related
Hi All!
I am trying to create a listView with the same row layout. But I am changing the elements of the row dynamically. From the diagram above, you can see that I populate my listView with rows but then the buttons on the row will have to be different based on the type of row. The rest of the information in the row is the same.
Is there a way I can pass a flag into the adapter to make it add/remove elements from the layout based on the type of row? My adapter extends BaseAdapter.
Yes, Make your ListView adapter take a model that contains a flag as such in my answer.
This should work if you are converting your JSON object to a specific POJO with a parser like GSON. If you are trying to load your adapter from a JSON object I would recommend against that, so good luck.
public class Row{
private RowType rowType;
//all other row attributes
}
public enum RowType{
YesNo, Cancel, //all other possible scenarios
}
public class YourAdapter extends BaseAdapter{
private List<Row> rowsToPopulate;
//Override appropriate methods
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//load your view etc....
//Check the flag to load appropriate fragment
switch(rowsToPopulate.get(position).getRowType()){
case YesNo:
//Load your yes no fragment to your row view
case Cancel:
//Load your cancel fragment to your row view
}
return yourView;
}
This information should be contained in the model that the adapter knows about.
In the getView(..) method, you should be able to check if <model>.getType() is a specific type. If so, you can set visibility of specific components in your layout and change the UI accordingly.
If the type is not a part of your response, you can keep a Map<Model, Type> inside the adapter and update the adapter when you have new data, and have a convenience method to convert this to a list of model objects to display in the UI.
I’m new to Android and have a simple question. Currently I’m working on a products application that allows users to add, remove and browse variety of products. The application uses a predefined XML-based layout file as a template that fills the entire screen to show the current product details. When the user adds a new product, I want to re-use the same layout file but populate it with the new product’s information. Also, I want to keep the previously added products (e.g. an ArrayList) and the user can browse this list by sliding horizontally (left-to-right or right-to-left). Now, what is the best thing to use to represent each product (View, sub-view, …etc.), and how to reuse the same XML-based layout file to display different products’ details. Please excuse my English and thank you in advance for the help
You can create a new class that extends the ArrayAdapter and then override the getView() method to inflate your custom layout. getView() will return the View for a single row. This way you can reuse your layout. So it will look something like:
public class ProductAdapter extends ArrayAdapter<Product> {
private LayoutInflater li;
public ProductAdapter(Context context, List<Product> products) {
super(context, 0, products);
li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the product of the position
Product product = getItem(position);
View v = convertView;
if ( v == null ) {
// Your custom layout file for a single row in the list.
v = li.inflate(R.layout.product_row, null);
}
// Populate your view here. Use v.findViewById().
return v;
}
}
To show the list in an ListActivity use:
// The variable products is your initial list of products.
ProductAdapter adapter = new ProductAdapter(this, products);
setListAdapter(adapter);
When you add a product you can add this to your ArrayAdapter by calling either the adapter.add() (if you want to add your product at the end of the list) or insert() (to specify where in the list of products you want to insert the new product) method on the ProductAdapter. Afterwards you can call adapter.notifyDataSetChanged() to notify your adapter that the data has changed and that the list has to be refreshed.
What you are describing is implemented by the ViewPager. There's a blog post on the developer site in addition to the API reference.
To implement it, you'll need to create a PagerAdapter subclass to fill in the details of each view for the ViewPager.
I have a basic object called Employee. You can retrieve an Employee's name and id using .getName() and .getId().
I want to use Jeff Sharkey's SeparatedListAdapter to build a sectioned list. For the list items though, I need to use my custom Employee objects for the items instead of just lists of Strings.
In the included examples for the SeparatedListAdapter, he uses an ArrayAdapter<String> and a SimpleAdapter() for populating the list.
Is there any way to use a custom object/class, like my Employee class? The reason I'm needing to do this, is that when I click on an item in the list, I want to retrieve the actual Employee object that I used for that item and then retrieve the ID of the employee so I can display information pertaining to that Employee.
I'm a little bit confused on how to use Adapters properly. Should I make my own adapter or something?
You'll need to implement your custom adapter. Ex:
class CustomAdapter extends ArrayAdapter<Employee>
and when use it on SeparatedListAdapter:
CustomAdapter workersAdapter = new CustomAdapter(this, resourceID, workersList);
SeparatedListAdapter separated = new SeparatedListAdapter(this);
...
separated.addSection("Workers", workersAdapter);
Edit:
Overrride getView Method in your CustomAdapter to create views with Employee info. Like this:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if(convertView == null){
view = convertView;
}else
view = mInflater.inflate(R.layout.your_row, null);
Employee e = getItem(position);
((TextView)view.findViewById(R.id.textview_id)).setText(e.getId());
//...
return view;
}
So I've been modifying the notepad tutorial code: http://developer.android.com/resources/tutorials/notepad/notepad-ex1.html .
Basically what I want to do is to create specific layout styles (i.e. background color) for different rows within the ListView based on the content. So for example, the text for the title is "1" so the background of that row will be red. Or, if the text for the title is "2" then the background of that row (or list item) will be green.
What I'm trying to accomplish is to have a summary of the the rows in the database and color-code each row based upon what category (numerical field) the item is stored as.
They use SimpleCursorAdapter, and you need to write your own in order to change the output. In your adapter, which handles the presentation of your data, you can override the method getView(). Then populate each row with the data from the db. And depending on the data, set a different background color.
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.my_layout, null);
}
Cursor.moveToPosition(position);
ImageView img = (ImageView)v.findViewById(R.id.bg);
if (Cursor.getString(Cursor.getColumnIndex("column")).equals("black")) {
img.setImageBackground(Color.Black);
}
return v;
Hwa Rang's answer is correct. You might also want to use the getItem method to get the item at a particular position on the list to determine what type of data it is. Then change the background color of that row in getView method
I'm trying to do a List that shows an image and a simple text describing the image.
In my search on internet I found many ways to do this. Some people using ArrayAdapter, others using SimpleCursorAdapter. One thing I notice, many people are creating classes inheriting from ListActivity and in the setListAdapter method they are inserting other classes derived from Array or SimpleCursor adapter.
First question: is this the best way to do this?
I created a LinearLayout with a ListView inside. And to insert rows, another layout was created with an ImageView and a TextView.
Second question: is this correct?
I'm confusing about creation of this type of component. Is this the correct way to do this?
Yes, this is correct, although you will need to use a CursorAdapter instead of a SimpleCursorAdapter, since the point of a SimpleCursorAdapter is to populate a row with only a TextView in it.
You will have a getView method on your CursorAdapter that expands your row layout:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) { // we don't have a recycled view
convertView = LayoutInflator.from(getContext()).inflate(
R.layout.row, parent, false);
}
// setup our row
TextView text = (TextView) convertView.findViewById(R.id.text_view);
text.setText( ... );
ImageView image = (ImageView) convertView.findViewById(R.id.image_view);
image.setImageBitmap( ... );
return convertView;
}
When you're setting the text and image of your views, you can use adapter methods like getItem to access the underlying data you need.