学习笔记4: ListView使用总结

1.ListView常用优化

重用convertView, 使用viewHolder setTag(),getTag()减少使用findViewByID

@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    ViewHolder holder = null;
    //判断是否缓存
    if(convertView == null){
        holder = new ViewHolder();
        //实例化布局
        LayoutInflater mInflater = LayoutInflater.from(lvActivity.this);
        convertView = mInflater.inflate(R.layout.lv_item_layout,null);
        holder.tv = (TextView)convertView.findViewById(R.id.textView);
        holder.iv = (ImageView)convertView.findViewById(R.id.imageView);
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder)convertView.getTag();
    }
    holder.iv.setBackgroundResource(R.drawable.a);
    holder.tv.setText(getItem(i).toString());
    return convertView;
}

public final class ViewHolder{
    public TextView tv;
    public ImageView iv;
}

2.ListView的一些常用效果 (xml里面的listview标签下)

//无分隔线

android:divider="@null"

//灰色分隔线
android:divider="@android:color/darker_gray"
android:dividerHeight="10dp"

//没有滚动条
android:scrollbars="none"

//没有点击效果(系统默认会变成淡灰,这里也可以设成图片
android:listSelector="#00000000"

//添加刷新后,自动跳到刚才添加的那条

data.add(data.size(),"我是新来的");
adapter.notifyDataSetChanged();
lv.setSelection(N);

3.获取可见的某个item进行修改

int num = lv.getChildCount(); //获取可见的条目总数
View view1 = lv.getChildAt(3); //获取可见的第N个条目,注意:这个值不能大于num-1。 多了就会空指针
((TextView) view1.findViewById(R.id.textView)).setText("我被修改了"); //修改内容

4.滑动监听

lv.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction()){
            case MotionEvent.ACTION_DOWN:
                Toast.makeText(lvActivity.this,"触摸屏幕",Toast.LENGTH_SHORT).show();
                break;
            case MotionEvent.ACTION_MOVE:
                Toast.makeText(lvActivity.this,"滑动",Toast.LENGTH_SHORT).show();
                break;
            case MotionEvent.ACTION_UP:
                Toast.makeText(lvActivity.this,"离开屏幕",Toast.LENGTH_SHORT).show();
                break;
        }
        return false;
    }
});

lv.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView absListView, int state) {
        switch (state) {
            case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                Toast.makeText(lvActivity.this,"离开屏幕1",Toast.LENGTH_SHORT).show();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                Toast.makeText(lvActivity.this,"惯性滚动",Toast.LENGTH_SHORT).show();
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                Toast.makeText(lvActivity.this,"触摸屏幕1",Toast.LENGTH_SHORT).show();
                break;
        }
    }

    @Override
    public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        //滚动时一直回调
        //firstVisibleItem 当前可见的第一个Item的ID
        //visibleItemCount 当前可见的item 总数(显示一小半也算)
        //totalItemCount 整个listView的item 总数
    }
});

5.聊天ListView 及多种布局的ListView

a.准备好不同的布局文件

b.在适配器里多重写两个方法(这里只有2种type,随便写了下)
@Override
public int getItemViewType(int position) {
    if(position%2 == 0){
        return 1;
    }
    return 0;
}

@Override
public int getViewTypeCount() {
    return 2;
}
c.在getView()里面根据不同的type加载不同的布局,再设置内容就可以了
@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    ViewHolder holder = null;
    //判断是否缓存
    if(convertView == null){
        holder = new ViewHolder();
        //根据不同的type加载布局
        LayoutInflater mInflater = LayoutInflater.from(chatActivity.this);
        if(getItemViewType(i)==1){
            convertView = mInflater.inflate(R.layout.chat_me, null);
        }
        else {
            convertView = mInflater.inflate(R.layout.chat_you, null);
        }
        holder.tv = (TextView)convertView.findViewById(R.id.textView);
        convertView.setTag(holder);
    }
    else{
        holder = (ViewHolder)convertView.getTag();
    }
    holder.tv.setText(getItem(i).toString());
    return convertView;
}

public final class ViewHolder{
    public TextView tv;
}

6.关于ListView里面数据混乱

网上有大量的经验,这里只做个人总结。
1.出现数据混乱的主要原因是在getView的时候重用了 convertView 和 viewHolder。
2.getView() 的时候会根据 item 数量的多少,重复的构造每一个item.
3.当我们滑动时,有的item消失,有的item出现。为了节省资源,系统会把消失的item当做容器,放入新item的内容展示出来。
4.在这个时候,我们会设置一些新的值。 而如果我们没有设置新的值,就会默认使用缓存里面的值。 所以就会数据混乱。
5.所以在使用listView的时候,最好保证convertview里的每一个内容都给了新的值,如果为空可以给个空值,这样不会出现混乱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ListView根据内容自动调整列宽可以让界面更加美观和易于使用。以下是实现的步骤: 1. 确定ListView的列数和列名。 2. 将ListView的View属性设置为GridView。 3. 为每个列设置一个HeaderTemplate,其中包含一个TextBlock控件。 4. 在ListView的Loaded事件中添加代码,使用ActualWidth属性设置每个列的宽度。 5. 在ListView的SizeChanged事件中添加代码,使用ActualWidth属性设置每个列的宽度。 下面是一个示例,演示如何在WPF中自动调整ListView列宽: ```xml <ListView ItemsSource="{Binding Items}" Loaded="ListView_Loaded" SizeChanged="ListView_SizeChanged"> <ListView.View> <GridView> <GridViewColumn Header="ID" Width="Auto"> <GridViewColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </GridViewColumn.HeaderTemplate> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding ID}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="Name" Width="Auto"> <GridViewColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </GridViewColumn.HeaderTemplate> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="Age" Width="Auto"> <GridViewColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </GridViewColumn.HeaderTemplate> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Age}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView> ``` ```csharp private void ListView_Loaded(object sender, RoutedEventArgs e) { var listView = sender as ListView; if (listView != null && listView.Items.Count > 0) { var gridView = listView.View as GridView; if (gridView != null) { double workingWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; for (int i = 0; i < gridView.Columns.Count; i++) { gridView.Columns[i].Width = workingWidth / gridView.Columns.Count; } } } } private void ListView_SizeChanged(object sender, SizeChangedEventArgs e) { var listView = sender as ListView; if (listView != null && listView.Items.Count > 0) { var gridView = listView.View as GridView; if (gridView != null) { double workingWidth = listView.ActualWidth - SystemParameters.VerticalScrollBarWidth; for (int i = 0; i < gridView.Columns.Count; i++) { gridView.Columns[i].Width = workingWidth / gridView.Columns.Count; } } } } ``` 在这个示例中,我们创建了一个包含三列的ListView,每个列的宽度都设置为Auto。在ListView的Loaded和SizeChanged事件中,我们使用ActualWidth属性计算每个列的宽度,以便使列宽适合ListView的大小。当ListView的大小改变时,我们重新计算列宽。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值