Getting started with Android (V) UI – unit and size, listview

Original link: http://www.orlion.ga/453/

1、 Units and dimensions

The following units are available in the layout file: Px, Pt, DP, sp

PX: is the pixel, the smallest element unit visible on the screen.

Pt: it's a pound. A pound is equal to 1 / 72 inch. Generally, Pt will be used as the unit of font.

The effect of controls with the same PX number on mobile phone screens with different resolutions is different, and Pt is similar to PX

DP: is a density independent pixel, also known as dip. Compared with Px, it has the same display proportion in screens with different densities

SP: is a scalable pixel. It adopts the same design concept as DP to solve the problem of text size adaptation

The density in Android is the number of pixels contained in the screen, usually in dpi. For example, the width of a mobile phone screen is 2 inches and the length is 3 inches. If its resolution is 320 * 480 pixels, the mobile phone screen is 160dpi. If the resolution is 640 * 960, the density of the screen is 320dpi.

According to Android, 1DP is equal to 1px on a 160dpi screen and 2px on a 320dpi screen.

2、 Listview

1. Simple usage of listview

First, create a listviewtest project and let ADT automatically create activities for us. Then modify

activity_ The code in main.xml is as follows:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>
</LinearLayout>

Next, modify the code in mainactivity as follows:

public class MainActivity extends Activity {
    private String[] data = { "Apple", "Banana", "Orange", "Watermelon",        "Pear", "Grape", "Pineapple", "StrawBerry", "Cherry", "Mango" };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            MainActivity.this, android.R.layout.simple_list_item_1, data);
        ListView listView = (ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
    }
}

Since listview is used to display a large amount of data, we should provide the data first. These data can be downloaded from the Internet or read from the database, depending on the specific application scenario. Here we simply use a data array to test, which contains the names of many fruits.

However, the data in the array cannot be directly passed to the listview, and we need to use the adapter to complete it. Android provides many adapter implementation classes, of which I think the best is arrayadapter. It can specify the data type to be adapted through generics, and then pass in the data to be adapted in the constructor. Arrayadapter has multiple constructor overloads. You should choose the most appropriate one according to the actual situation. Here, because the data we provide are strings, we specify the generic type of arrayadapter as string, and then pass in the constructor of arrayadapter the current context, the ID of listview sub item layout, and the data to be adapted. Notice that we used Android. R. layout. Simple_ list_ item_ 1 as the ID of the listview sub item layout, this is an Android built-in layout file. There is only one textview in it, which can be used to simply display a piece of text. The adapter object is built. Finally, you need to call the setadapter () method of listview to pass in the constructed adapter object, so that the association between listview and data is established. Now run the following program, as shown in the figure:

2. Add pictures to listview

The listview that can only display a paragraph of text is too monotonous. Now let's customize the listview interface so that it can display richer content. First, we need to prepare a group of pictures corresponding to each fruit provided above. Later, we need to have a pattern next to the name of these fruits. Then define an entity class as the adaptation type of listview adapter. Create a new class fruit. The code is as follows:

public class Fruit {
    private String name;
    private int imageId;
    public Fruit(String name, int imageId) {
        this.name = name;
        this.imageId = imageId;
    }
    public String getName() {
        return name;
    }
    public int getImageId() {
        return imageId;
    }
}

There are only two fields in the fruit class. Name represents the name of the fruit and ImageID represents the resource ID of the corresponding picture of the fruit. Then we need to specify a custom layout for the children of listview, and create a new fruit in the layout directory_ Item.xml, the code is as follows:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="10dip" />
</LinearLayout>

In this layout, we define an ImageView to display the picture of fruit and a textview to display the name of fruit.

Next, you need to create a custom adapter that inherits from the arrayadapter and specifies the generic as the fruit class. Create a new class fruitadapter. The code is as follows:

public class FruitAdapter extends ArrayAdapter<Fruit> {
    private int resourceId;
    public FruitAdapter(Context context, int textViewResourceId,        List<Fruit> objects) {
        super(context, textViewResourceId, objects);
        resourceId = textViewResourceId;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Fruit fruit = getItem(position); // 获取当前项的Fruit实例
        View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
        ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
        TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource(fruit.getImageId());
        fruitName.setText(fruit.getName());
        return view;
    }
}

The fruitadapter overrides a set of constructors of the parent class to pass in the context, the ID and data of the listview child layout. In addition, it rewrites the getview () method, which will be called when each sub item is scrolled to the screen. In the getview method, first get the fruit instance of the current item through the getitem () method, and then use the layoutinflator to load the layout we passed in for this sub item, then call the findviewbyid () method of view to get the instances of ImageView and textview respectively, and call their setimageresource () and settext () methods respectively to set the displayed pictures and text, Finally, return the layout, so that our customized adapter is completed. Modify the code in mainactivity as follows:

public class MainActivity extends Activity {
    private List<Fruit> fruitList = new ArrayList<Fruit>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits(); // 初始化水果数据
        FruitAdapter adapter = new FruitAdapter(MainActivity.this,        R.layout.fruit_item, fruitList);
        ListView listView = (ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
    }
    private void initFruits() {
        Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
        fruitList.add(apple);
        Fruit banana = new Fruit("Banana", R.drawable.banana_pic);
        fruitList.add(banana);
        Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
        fruitList.add(orange);
        Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
        fruitList.add(watermelon);
        Fruit pear = new Fruit("Pear", R.drawable.pear_pic);
        fruitList.add(pear);
        Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
        fruitList.add(grape);
        Fruit pineapple = new Fruit("Pineapple", R.drawable.pineapple_pic);
        fruitList.add(pineapple);
        Fruit strawBerry = new Fruit("StrawBerry", R.drawable.strawBerry_pic);
        fruitList.add(strawBerry);
        Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
        fruitList.add(cherry);
        Fruit mango = new Fruit("Mango", R.drawable.mango_pic);
        fruitList.add(mango);
    }
}

As you can see, an initfruits () method is added here to initialize all fruit data. Pass in the name of the fruit and the corresponding picture ID in the constructor of the fruit class, and then add the created object to the fruit list. Then we created the fruitadapter object in the oncreate () method and passed the fruitadapter to the listview as an adapter. This completes the task of customizing the listview interface. Now rerun the program

, as shown in the figure:

3. Improve the operation efficiency of listview

The reason why the listview control is difficult to use is that it has many details that can be optimized, and the operation efficiency is a very important point. At present, the operation efficiency of our listview is very low, because the layout is reloaded every time in the getview () method of fruitadapter. When the listview scrolls quickly, it will become a performance bottleneck. Carefully observe that there is also a convertview parameter in the getview () method, which is used to convert the previously loaded

The layout is cached so that it can be reused later. Modify the code in the fruitadapter as follows:

public class FruitAdapter extends ArrayAdapter<Fruit> {
    ……
    @Override
    public View getView(int position, ViewGroup parent) {
        Fruit fruit = getItem(position);
        View view;
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);
        } else {
            view = convertView;
        }
        ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
        TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource(fruit.getImageId());
        fruitName.setText(fruit.getName());
        return view;
    }
}

As you can see, now we have made a judgment in the getview () method. If the convertview is empty, we will use layoutinflator to load the layout. If it is not empty, we will directly reuse the convertview. This greatly improves the operation efficiency of listview and shows better performance when scrolling quickly.

However, at present, our code can continue to be optimized. Although the layout will not be loaded again, the findviewbyid () method of view will be called every time in the getview () method to obtain the instance of the control. We can use a viewholder to optimize this part of the performance and modify the code in the fruitadapter, as shown below:

public class FruitAdapter extends ArrayAdapter<Fruit> {
    ……
    @Override
    public View getView(int position, ViewGroup parent) {
        Fruit fruit = getItem(position);
        View view;
        ViewHolder viewHolder;
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);
            viewHolder = new ViewHolder();
            viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
            view.setTag(viewHolder); // 将ViewHolder存储在View中
        } else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag(); // 重新获取ViewHolder
        }
        viewHolder.fruitImage.setImageResource(fruit.getImageId());
        viewHolder.fruitName.setText(fruit.getName());
        return view;
    }
    class ViewHolder {
        ImageView fruitImage;
        TextView fruitName;
    }
}

We have added an internal class viewholder to cache the instance of the control. When convertView is empty, create a ViewHolder object and store all instances of the control in ViewHolder, then call View's setTag () method to store ViewHolder objects in View. When convertview is not empty, call the gettag () method of view to retrieve the viewholder. In this way, all instances of the control are cached in the viewholder, so it is not necessary to obtain the control instance through the findviewbyid () method every time. After these two steps of optimization, the operation efficiency of our listview is very good.

4. Click event of listview

After all, the scrolling of listview only meets our visual effect, but if the sub items in listview cannot be clicked, this control has no practical use. Therefore, in this section, we will learn how listview can respond to user click events. Modify the code in mainactivity as follows:

public class MainActivity extends Activity {
    private List<Fruit> fruitList = new ArrayList<Fruit>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        FruitAdapter adapter = new FruitAdapter(MainActivity.this, fruitList);
        ListView listView = (ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,                int position, long id) {
                Fruit fruit = fruitList.get(position);
                Toast.makeText(MainActivity.this, fruit.getName(),                Toast.LENGTH_SHORT).show();
            }
        });
    }
    ……
}

We can see that we use setonitemclicklistener() method to register a listener for listview. When a user clicks any sub item in listview, it will call back onitemclick() method. In this method, we can judge which sub item the user clicks through the position parameter, and then get the corresponding fruit, And display the name of the fruit through toast. Rerun the program and click watermelon

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>