Android self-learning course-ListView is simplified to deep, androidlistview
Some time ago I learned RecyclerView and found that I felt more obvious about ListView. So I decided to sort out the previously checked ListView. After all, before the popularity of 5.0, ListView was useful. As always, we start from a simple one. -- Standing on the shoulders of giants
Translated from: Baidu.
Using an ArrayAdapter with ListView
In android development, we often useListViewTo display the requirements of a set of vertical scrolling lists, we will useAdapterFill in data. The simplest Adaper isArrayadapterBecause this adapterArrayListObjectViewList to be loadedListView.
Row View reconfiguring
When Adapter andListViewMake sure that you understand how the View recycle mechanism works.
When yourListViewContact the adapter. The adapter will list each row of the InstanceListViewIt is filled with sufficient items (items fills the total height of the ListView). In this case, no additional row List objects are created in the memory.
Instead,When you scroll down the list, the Items that exit the screen will be saved to the memory for later use., And then, when each new row list enters the screen,The row list stored in the memory will be reused.In this way, even if there are 1000 lists, only seven rows of lists of views need to be instantiated or saved in memory. This is an intuitive overview of recycling:
This is another picture related to recycling views.
Please refer to the ListView in another guide (I personally think there is a better choice and I will write a blog later) to see how this works to optimize the performance of your list.
Using a Basic ArrayAdapter
To use basicArrayAdaper, We only need to instantiate an adapter and connect the adapter to the ListView. Step 1: Initialize an adapter.
Adapter<String> itemsadapter = new ArrayAdapter<String> (this,android.R.layout.simple_list_item_1,items);
ArrayAdapter needs to declare the item when it is convertedView type(StringIn this case), and then receives three parameters: context (activity instance), XML item layout, and the array date. Note that we have selected
Simple_list_item_1, which is a simple applicationTextViewAs the layout for every Items.
Now, we need this adapter to connect to the ListView for filling,
ListView listView = (ListView) findViewById(R.id.lvItems);listView.setAdapter(itemsAdapter);
By default, this will now convert each item in the data array into a view by callingtoString
On the item and then assigning the result as the value ofTextView
(Simple_list_item_1.xml) that is displayed as the row for that data item. (I can't translate it. I 'd like to ask a good person to guide the translation ). If your application requires more complex changes in Item and View, we need to create a custom ArrayAdapter to replace it.
Using a Custom ArrayAdapter (prepare a data template and a view template)
When we want to display your custom List in the List, we need to use the custom XML layout file for every Items. To complete this step, we need to create a customArrayAdapter. See this repo for the source code.
In the first step, we often define a template to describe the data required for each Item in the List.
Defining the Model
Create a Java object to define certain fields, such as User class
public class User { public String name; public String hometown; public User(String name, String hometown) { this.name = name; this.hometown = hometown; }}
Creating the View Template
Next, we need to create an XML layout file to represent the template of each Item, res/layout/item_user.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/tvName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Name" /> <TextView android:id="@+id/tvHome" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="HomeTown" /></LinearLayout>
Defining the Adapter
Next, we need to define the Adapter and describe the process of converting a Java object to a View (inGetViewMethod ). The immature method is as follows (no cache is available ):
public class UsersAdapter extends ArrayAdapter<User> { public UsersAdapter(Context context, ArrayList<User> users) { super(context, 0, users); } @Override public View getView(int position, View convertView, ViewGroup parent) { // Get the data item for this position User user = getItem(position); // Check if an existing view is being reused, otherwise inflate the view if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_user, parent, false); } // Lookup view for data population TextView tvName = (TextView) convertView.findViewById(R.id.tvName); TextView tvHome = (TextView) convertView.findViewById(R.id.tvHome); // Populate the data into the template view using the data object tvName.setText(user.name); tvHome.setText(user.hometown); // Return the completed view to render on screen return convertView; }}
The Adapter has a constructor and a getView () method to describe.Transition between data items and views.
GetView () is the method used to return the actual view placed in the ListView at a specific position.
Attaching the Adapter to a ListView
Now, we can use the Adapter in the Activity to show that the Items array is embedded into the ListView:
// Construct the data sourceArrayList<User> arrayOfUsers = new ArrayList<User>();// Create the adapter to convert the array to viewsUsersAdapter adapter = new UsersAdapter(this, arrayOfUsers);// Attach the adapter to a ListViewListView listView = (ListView) findViewById(R.id.lvItems);listView.setAdapter(adapter);
At this moment, the ListView control is now successfully bound to the user group data.
Populating Data into ListView
Once the adapter is connected, Items will be automatically filled in the ListView Based on the content in the array.
We can add a new Item to the adapter:
// Add item to adapterUser newUser = new User("Nathan", "San Diego");adapter.add(newUser);// Or even append an entire new collection// Fetching some data, data has now returned// If data was JSON, convert to ArrayList of User objects.JSONArray jsonArray = ...;ArrayList<User> newUsers = User.fromJson(jsonArray)adapter.addAll(newUsers);
This will append the new Items to the List. We can also clear all the lists at any time, as long as one sentence:
adapter.clear();
Now we can add, delete, and modify users, and the Items in the ListView will automatically make corresponding reflection.
Constructing Models from External Source (build model from External Source)
To create a model instance, we may load data from external sources (that is, databases or rest json APIs). Therefore, we should create two additional methods for each model, A List or a single Item can be constructed if the data comes from the json api.
public class User { // Constructor to convert JSON object into a Java class instance public User(JSONObject object){ try { this.name = object.getString("name"); this.hometown = object.getString("hometown"); } catch (JSONException e) { e.printStackTrace(); } } // Factory method to convert an array of JSON objects into a list of objects // User.fromJson(jsonArray); public static ArrayList<User> fromJson(JSONArray jsonObjects) { ArrayList<User> users = new ArrayList<User>(); for (int i = 0; i < jsonObjects.length(); i++) { try { users.add(new User(jsonObjects.getJSONObject(i))); } catch (JSONException e) { e.printStackTrace(); } } return users; }}
For more details, check out our guide on converting JSON into a model. If you are not using a JSON source for your data, you can safely skip this step.
(I haven't met it yet. I feel like it's important)
Improving Performance with the ViewHolder Pattern
To improve performance, we shocould modify the custom adapter by applyingViewHolderPattern which speeds up the population of the ListView considerably by caching view lookups for smoother, faster item loading:
public class UsersAdapter extends ArrayAdapter<User> { // View lookup cache private static class ViewHolder { TextView name; TextView home; } public UsersAdapter(Context context, ArrayList<User> users) { super(context, R.layout.item_user, users); } @Override public View getView(int position, View convertView, ViewGroup parent) { // Get the data item for this position User user = getItem(position); // Check if an existing view is being reused, otherwise inflate the view ViewHolder viewHolder; // view lookup cache stored in tag if (convertView == null) { viewHolder = new ViewHolder(); LayoutInflater inflater = LayoutInflater.from(getContext()); convertView = inflater.inflate(R.layout.item_user, parent, false); viewHolder.name = (TextView) convertView.findViewById(R.id.tvName); viewHolder.home = (TextView) convertView.findViewById(R.id.tvHome); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } // Populate the data into the template view using the data object viewHolder.name.setText(user.name); viewHolder.home.setText(user.hometown); // Return the completed view to render on screen return convertView; }}
In this example, we use a private static class calledViewHolder. In practice, callFindViewById ()It is really very slow. If your adapter calls him every time and calls her for every row and column, you will soon find a performance problem. What ViewHolder does is cache the call.FindViewById ()This method. Once your ListView reaches the maximum number of rows it can display on the screen, Android will be very smart to recycle the views of these rows. We will test whether a View (the View of an Item) is recycled after if (convertView = Null. If it is not Null, we can use the recycled View, and we can change its value. Otherwise, we need to get a new View. The magic behind this issetTag()
Method which lets us attach an arbitrary object onto a View object, which is how we save the already inflated View for future reuse. (The magic behind this is the setTag () method, which allows us to attach any object to the View object. This is how we save the instantiated View for future use.
Beyond ViewHolders
Customizing Android ListView Rows by Subclassing describes a strategy for obtaining instances of child views using a similar approach as a ViewHolder but without the explicit ViewHolder subclass.
References
- Http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
- Http://www.doubleencore.com/2013/05/layout-inflation-as-intended/
- Http://www.bignerdranch.com/blog/customizing-android-listview-rows-subclassing/
Data Search section:
Http://www.cnblogs.com/xiangtailiang/p/3379543.html
Http://www.javacodegeeks.com/2013/09/android-viewholder-pattern-example.html
Http://www.codeofaninja.com/2013/09/android-listview-with-adapter-example.html
Http://stackoverflow.com/questions/4145602/how-to-implement-a-view-holder
Http://stackvoid.com/