最常用的控件———ListView

ListView

由于屏幕的有限,若是想看到全部内容则需要把屏幕外的数据滚到屏幕内,同时已经在屏幕上的信息会滚动出屏幕外。ListView就是可以实现这种功能的控件。

1、简单的用法

先在布局文件里添加一个ListView控件;
然后在Mainactivity中将数据与控件联系起来。首先呢是使用ArrayAdapter泛型指定数据类型是String,然后在ArrayAdapter构造函数里依次传入上下文,以及ListView子项布局,以及要适配的数据(可以来自数据库,简单定义可以是一个数组)。其中我们的子项布局使用android.R.layout.simple_list_item_1(这是一个Android内置的布局文件,里面只有一个简单的TextView显示数据)。
最后,还需要调用ListView的setAdapter()方法,将搭建好的适配器对象传递进去。

public class MainActivity extends AppCompatActivity {
//提前定义的数组数据
private String[] data={"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango","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=findViewById(R.id.list_view);
        listView.setAdapter(adapter);
    }
}

在这里插入图片描述

2、定制ListView的界面

实现一组能实现图片的ListView。
1)首先定义一个水果类,创建构造函数。

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;
}
}

2)然后,要为ListView的子项指定一个我们自定义的布局,在layout目录下新建一个fruit_item.xml。一个imageview显示水果图片,一个显示水果名称。


   
    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:scaleType="fitStart"
        android:maxHeight="30dp"
        android:maxWidth="30dp"
        android:id="@+id/fruit_image"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/fruit_name"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"/>

3)创建一个自定义的适配器FruitAdapter,这个适配器继承自ArrayAdapter,并将泛型指定为Fruit类。在FruitAdapter中重写构造函数和getview方法。getView方法在每个子项被滚动到屏幕内的时候会被调用,首先通过getItem()方法得到当前Fruit实例,然后会使用LayoutInflate来为这个子项加载我们传入的布局。
在LayoutInflate的inflate()方法接收三个参数,第三个是false表示只让我们在父布局中声明的layout属性生效,但不会为这个view添加父布局,因为一旦view有了父布局之后,他就不能再添加到ListView中。调用View的findViewById()方法分别获得Imageview和TextView的实例,并分别调用他们的setImageResource()和setText()方法来显示图片和文字,最后将布局返回。

public class FruitAdapter extends ArrayAdapter<Fruit>{
    private  int resoureid;
    //重写父类的一组构造函数 将上下文和ListView的子项布局和数据传递进来。
    public FruitAdapter(Context context, int textViewResouceid, List<Fruit> objects){
        super(context,textViewResouceid,objects);
        resoureid=textViewResouceid;
    }
    //重写getview方法 这个方法在每个子项滚动到屏幕内的时候会被调用
    public View getView(int position, View convertView, ViewGroup parent){
        Fruit fruit=getItem(position);//获取当前项的Fruit实例
        View view=LayoutInflater.from(getContext()).inflate(resoureid,parent,false);
        //调用View的findViewById()方法分别获得Imageview和TextView的实例,并分别调用他们的setImageResource()和setText()方法来显示图片和文字,最后将布局返回。
        ImageView fruitImage=view.findViewById(R.id.fruit_image);
        TextView fruitname=view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource(fruit.getImageid());
        fruitname.setText(fruit.getName());
        return view;
    }
}

4)接下来初始化水果的数据,在Fruit类的构造函数中将水果的名字和对应的图片的ID传入,然后把建好的对象添加进水果列表中。利用for循环是来添加两遍,让数据占满整个屏幕实现滚动的效果。接着在on
creat()方法中创建了FruitAdapter()对象,并将他作为适配器传给ListView。

 initFruits();//初始化水果
        //创建适配器
        FruitAdapter adapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
        ListView listView=findViewById(R.id.list_view);
        listView.setAdapter(adapter);
         private void initFruits(){
        for(int i=0;i<2;i++){
            Fruit apple=new Fruit("Apple",R.drawable.apple);
            fruitList.add(apple);
        }//其余水果类似

效果如图:在这里插入图片描述

3、提升ListView的运行效率

因为在FruitAdapter的getview方法中,每次都是将布局重新加载一遍,当ListView快速滚动时会成为性能的瓶颈。在getview方法中还有一个conerView参数,这个参数将之前加载好的布局缓存,可以对其判断,若是null,则使用LayoutInflater加载布局,不为null则直接对convertView进行重用。修改FruitAdapter中的代码。

 View view;
        if(convertView==null){
            view=LayoutInflater.from(getContext()).inflate(resoureid,parent,false);
        }else {
            view=convertView;
        }

4、ListView的点击事件

利用setOnItemClickListener()方法为ListView注册一个监听器,用户点击任何一个子项时回调onItemClick()方法,根据position判断是哪一个子项然后输出。在MainActivity里修改。

 listView.setOnItemClickListener(new AdapterView.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();
            }
        });

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Xamarin 中,ListView 是一个非常常见的控件,用于显示一个竖直滚动的列表。但如果我们需要实现一个横向滚动的列表,该怎么办呢?这时候,我们可以使用自定义的 ItemsControl 来实现这个功能。 ItemsControl 是一个用于显示一个集合的控件,它的每个元素都可以自定义显示方式。在本文中,我们会通过自定义 ItemsControl,实现一个横向滚动的列表。 首先,我们需要创建一个自定义控件,继承自 ItemsControl。在这个控件中,我们需要对 ItemContainerStyle 和 ItemsPanel 进行定义。 ItemContainerStyle 用于定义每个元素的样式,我们可以设置元素的大小、边距等属性。在本例中,我们设置元素宽度为 100,高度为自适应,并设置左右边距为 5。 ItemsPanel 用于定义元素的排列方式。在本例中,我们使用一个 StackPanel,设置 Orientation 为 Horizontal,这样子项就会水平排列。 下面是完整的代码实现: ```csharp using Xamarin.Forms; namespace MyNamespace { public class HorizontalItemsControl : ItemsControl { public HorizontalItemsControl() { // 设置样式 ItemContainerStyle = new Style(typeof(ViewCell)) { Setters = { new Setter { Property = ViewCell.WidthRequestProperty, Value = 100 }, new Setter { Property = ViewCell.MarginProperty, Value = new Thickness(5, 0) } } }; // 设置子项排列方式 ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Horizontal); } } } ``` 使用起来也非常简单,只需要在 XAML 中声明这个控件即可: ```xml <local:HorizontalItemsControl ItemsSource="{Binding MyItems}"> <local:HorizontalItemsControl.ItemTemplate> <DataTemplate> <!-- 这里放置每个元素的显示内容 --> </DataTemplate> </local:HorizontalItemsControl.ItemTemplate> </local:HorizontalItemsControl> ``` 其中,MyItems 指定了要显示的数据源,ItemTemplate 指定了每个元素的显示方式。 这样,我们就实现了一个简单的横向滚动列表。当然,这只是一个简单的示例,实际使用中可能还需要进行更多的定制和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值