I'm reading this tutorial http://android.amberfog.com/?p=296 . I have just a question: if I definire an xml layout like this one:
<LinearLayout>
<ListView/>
<TextView android:id="#+id/id1" />
<TextView android:id="#+id/id2" />
<ImageView android:id="#+id/id3" />
<TextView android:id="#+id/id4" />
</LinearLayout>
Now, suppose that to show the item type A I use the Textview id1 and id2: For the item type B I use id1 and the imageview id3. For the item type C id1, id2 and id3. For the item type D the id4, etc etc.
In a case like this, having textviews and imageviews (in the xml layout) which will not be used by every item in the listview, will it be slow (in performance)?
Thank you in advance
If you're using an adapter, you can create a separate layout for each type of item and inflate a different layout in getView method of your adapter.
Related
I have a RecyclerView as follows
<android.support.v7.widget.RecyclerView
android:id="#+id/drawerList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/nav_header_container"
android:layout_marginTop="15dp" />
I have a string array like this
<string-array name="my_array">
<item>#string/item_1</item>
<!--<item>#string/item_2</item>-->
<item>#string/item_3</item>
<item>#string/item_4</item>
<item>#string/item_5</item>
<item>#string/item_6</item>
This string array is used to display data in RecyclerView. I want to display a textview alongside with item_4, Is it possible? How to make it?
From Activity Pass this list to RecyclerView adapter
try {
String[] array = getApplicationContext().getResources().getStringArray(R.array.my_array);
List<String> list = new ArrayList<String>();
list = Arrays.asList(array);
//pass this list to RecyclerView adapter
}catch (Exception e){e.printStackTrace();}
In your onBindViewHolder method just put a check for the element you want to display differently and do what you want to do with it.
Some solutions:
1.- You can concat a string to the 4th item when you check the position in the onBindViewHolder.
2.- You can create a layout and inflate it on onCreateViewHolder which has two textViews one for the items and one for the text that will go next to it. When you detect that you need to show the second textview change the content and the visibility of the textview.
<LinearLayout android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:id="#+id/items"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textViewNextToItemOfChoice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
</LinearLayout>
Then on code you just change the visibility of textview "textViewNextToItemOfChoice" and the content of it.
I think you should make an object (You own model) instead of using just an array of string to populate the list. In that way you can create an object with 2 Strings and in the adapter when you check if it has both string you show them.
actually my problem is same as this guy's.But I don't know how to resolve it.Here's my listview xml file.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="3"
android:background="#CCCCCC"
android:id="#+id/tabs">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#CCCCCC"
android:textSize="20sp"
android:textColor="#000000"
android:text="#string/NewTask"
android:id="#+id/tab1"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#CCCCCC"
android:layout_weight="1"
android:textSize="20sp"
android:textColor="#000000"
android:text="#string/Friends"
android:id="#+id/tab2"
/>
<Button
android:layout_width="fill_parent"
android:background="#CCCCCC"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_weight="1"
android:text="#string/AddPeople"
android:textSize="20sp"
android:id="#+id/tab3"
/>
</LinearLayout>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#000000"
android:layout_below="#+id/tabs"
/>
</RelativeLayout>
I am trying to call a function in my listactivity from the onpostExecute of my AsyncTask class.
Here's the function of my listactivity.
public void SetImage(Bitmap bmp,int index)
{
View v = this.ls.getChildAt(index);
ImageView img = (ImageView)v.findViewById(R.id.tasks_userimg);
img.setImageBitmap(bmp);
}
This bmp is the bitmap downloaded in the asynctask class and ls is the listview and the index is the index of the item in the listview.When the postexecute runs I call this function with the arguments to update the listview item image.
The problem is exactly same as I've mentioned in the link i.e when I scroll it gives me error.But he solved the problem by changing the layout width of listview but it is not working here.
Seems that like many others , you have some problems with this special view .
I highly recommend watching the lecture "the world of listView".
They talk about a lot of topics related to listView , including the topic of calling getView multiple times on the same view. In short , the reason why it occurs is because getView is also called for measuring the listView items . You can use (and should) use the convertView in order to avoid un-needed inflating and fetching of data .
About the question itself , you should not use findViewById on the listView items , since they are getting re-used . For example , a view that was set for the 0-th position may be set to the 7-th position in case the user has scrolled down .
if you wish to update a single item from the listView , you can use something like this:
// itemIndex is the index of the item to update
final View v=listView.getChildAt(itemIndex-listView.getFirstVisiblePosition());
//now you update your view according to what you wish .
//you must of course handle the cases that you can't get the view .
Of course , once you do it , you will also have to update your data behind the adapter , so that the next time the user scrolls to this item , it will have the bitmap shown to it.
What you should do depends on the asyncTask you've used .
I assume that you download multiple bitmaps while the listview fills its items . If that's the case , check out this sample , or use my suggestion : have an asyncTask for each viewHolder you have . For each time getView is called , cancel the old one and create a new one for the current item.
1) Define your custom adapter
2) Apply holder pattern
3) Use some image uploader (for example this)
Take a look simple example
I want some tips in how to complete one task.
We got three EditTexts, a button and a llistview.
The idea here is when the button is pressed, the texts from the three EditTexts will be show in a listview, side by side, giving the impression that we got a table here.
The problem here is I don't know how to do it. I've tried to search something on the net, but I just got nothing.
I'd really appreciate if you could help.
Thaks for the attention and have a nice day.
There are a couple ways to achieve what you want. If I'm understanding correctly you have a listview and a button. When you click the button, you want 3 editTexts to appear in your listview side by side so that it looks like a table.
The simplest solution is have your list item layout, inflated in your listadapter, simply be a linearlayout with weightSum="3" containing 3 edittexts with layout_weight="1" and layout_width="0dp"
so your list_item.xml would look something like:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="3">
<EditText android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
<EditText android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
<EditText android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"/>
</LinearLayout>
Then, in the onClick for your button, iterate through the children of the list row and set the visibilities to visible.
As for adding rows dynamically, use a listadapter and a collection and use the notifydatasetchanged to update the list when your collection gains/loses items.
I want to design below screen
When i press 'Add number' button, it will insert one entry in below scrollable layout. In that when i press 'X' button it should delete that particular row.
How to achieve this??
Any idea??
use
ViewGroup.addView(View view);
to add a view to some layout.
To create a layout dynamically, use:
TextView txtView=new TextView(this);
//Its an example, you can create layouts, buttons, image view, and other components.
To Delete a layout or view dynamically, getParent of layout, and delete, by:
ViewGroup.removeView(View view);
You should use a ListView which is backed by an ArrayList of Objects or Strings. When you want to remove an item from your ListView, remove the object from the ArrayList :
mData.remove(object);
and then notify the ListView that the date has changed :
mAdapter.notifyDataSetChanged();
Use a ListView for displaying the list of patterns
Create a custom layout for each list item. e.g.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="555*" />
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="matched 5 " />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="X" />
</LinearLayout>
Create a Custom Adapter class extending BaseAdapter
It can maintain a list for the patterns to be shown
In the getView method of the custom adapter -
inflate the xml
set the information (like pattern and number of matches) based on the index parameter, using the list
set onclick listener for the button (delete that item from list and call notifyDatasetInvalidated())
return the view.
On "Add Number" add item to the list in the adapter
I have a listview.
The list items must be populated using code and in the following pattern
The odd numbered list items must be placed aligned with the left side of the screen.
The even numbered list items must be place aligned with the right side of the screen.
The width must depend on the size of the content.
These task must be performed using code.
<LinearLayout android:id="#+id/list_item"
android:paddingLeft="5dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
<TextView android:id="#+id/text_view"
android:autoLink="all"
android:paddingTop="6dip"
android:paddingBottom="3dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:linksClickable="false"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#ff000000"
android:textSize="18sp" />
</LinearLayout>
note:i use cursor adapter to bind the data with listview
You must see Google I/O 2010 - The world of ListView to understand how ListView works.
For your situation in getView(...) method of your list adapter you could add something like this:
if(position%2==0){
//even
convertView.setGravity(Gravity.RIGHT);
} else{
//odd
convertView.setGravity(Gravity.LEFT);
}
In order to set width dependency on content change all "layout_width properties" to "wrap_content" in your xml above.
Also it would be useful to read ListView Tips & Tricks post series.
Hope I've got the question correctly.