上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

Android Studio安卓开发--ListView学习整理

guduadmin513月前

ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕。

1.ListView的简单用法

(1)activity_main.xml布局中加入ListView控件:(先占满整个布局的空间)

(2)MainActivity.java中使用ListView展示大量数据:

public class MainActivity extends AppCompatActivity {
     private String[]data={
            "Apple","Pig","Red",
            "Banana","Chicken","Yellow",
            "Orange","Cow","Pink",
            "Cherry","Sheep","Purple",
            "Pear","Cat","Green",
            "Snow","Rain","Sun"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayAdapteradapter = new ArrayAdapter(
                MainActivity.this, android.R.layout.simple_list_item_1,data);
        ListView listView = (ListView)findViewById(R.id.lv1);
        listView.setAdapter(adapter);
    }
}
  • 使用ArrayAdapter泛型类(指定为String)将数据传递给ListView,构造函数中依次传入当前上下文、ListView子项布局的id、以及要适配的数据。
  • android.R.layout.simple_list_item_1作为ListView子项布局的id,这是一个Android内置的布局文件,里面只有一个TextView,可用于简单地显示一段文本。
  • 最后调用listView.setAdapter(adapter),将构建好的适配器对象传递进去,这样ListView和数据之间的关联就建立完成了。

    Android Studio安卓开发--ListView学习整理,第1张Android Studio安卓开发--ListView学习整理,第2张

    2.定制ListView的界面

    (1)新建类Goods:

    package com.example.practice;
    public class Goods {
        private String name;
        private int imageId;
        public Goods(String name,int imageId)
        {
            this.name=name;
            this.imageId=imageId;
        }
        public String getName()
        {
            return name;
        }
        public int getImageId()
        {
            return imageId;
        }
    }
    

    (2)在activity_main.xml进行页面布局,包括ImageView图片和TextView文本:

    
        

    (3)创建一个自定义适配器,新建类GoodsAdapter:

    package com.example.practice;
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    import androidx.recyclerview.widget.RecyclerView;
    import java.util.List;
    //自定义适配器
    public class GoodsAdapter extends ArrayAdapter {
        private int resourceId;
        public GoodsAdapter(Context context, int textViewResourceId, List objects)
        {
            super(context,textViewResourceId,objects);
            resourceId=textViewResourceId;
        }
        @Override
        //getView方法是每个子项被滚动到屏幕内的时候都会被调用
        public View getView(int position, View convertView, ViewGroup parent)
        {
            Goods good=getItem(position);//获取当前good的实例
    //        View view= LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
            View view;
            if(convertView == null)
            {
                view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
            }
            else
            {
                view = convertView;
            }
            ImageView goodImage=(ImageView) view.findViewById(R.id.goods_image);
            TextView goodName=(TextView) view.findViewById(R.id.goods_name);
            goodImage.setImageResource(good.getImageId());
            goodName.setText(good.getName());
            return view;
        }
    }
    
    • 重写getView()方法,这个方法在每个子项被滚动到屏幕内的时候会被调用。
    • 在getView()方法中,首先通过getItem()方法获得当前项的Good实例,然后使用LayoutInflater来为这个子项加载传入的布局。
    • LayoutInflater的inflate()方法中第三个参数为false,表示只让我们在父布局中声明的layout属性生效,但不会为这个View添加父布局,因为一旦View有了父布局之后,它就不能再添加到LastView中了。
    • 其中convertView参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。如果convertView为null,则使用LayoutInflater去加载布局,如果不为null则直接对converView进行重用。这样就大大提高了ListView的运行效率,在快速滚动的时候也可以表现出更好的性能。

      (4)修改MainActivity中的代码,先初始化商品数据,之后使用ListView进行展示:

      package com.example.practice;
      import androidx.appcompat.app.AppCompatActivity;
      import android.os.Bundle;
      import android.view.View;
      import android.widget.AdapterView;
      import android.widget.ListView;
      import android.widget.Toast;
      import java.util.ArrayList;
      import java.util.List;
      public class MainActivity extends AppCompatActivity {
          private ListgoodsList=new ArrayList<>();
          private void initGood()
          {
              for(int i=0;i<2;i++)
              {
                  Goods good1=new Goods("apple",R.drawable.pic1);
                  goodsList.add(good1);
                  Goods good2=new Goods("banana",R.drawable.pic2);
                  goodsList.add(good2);
                  Goods good3=new Goods("pear",R.drawable.pic3);
                  goodsList.add(good3);
                  Goods good4=new Goods("orange",R.drawable.pic4);
                  goodsList.add(good4);
              }
          }
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
               initGood();
               GoodsAdapter adapter=new GoodsAdapter(MainActivity.this,R.layout.activity_main,goodsList);
              ListView listView=(ListView) findViewById(R.id.list_view);
              listView.setAdapter(adapter);
          }
      }

      Android Studio安卓开发--ListView学习整理,第3张

      3.ListView的点击事件

      (1)修改MainActivity中的代码:

               initGood();
               GoodsAdapter adapter=new GoodsAdapter(MainActivity.this,R.layout.activity_main,goodsList);
              ListView listView=(ListView) findViewById(R.id.list_view);
              listView.setAdapter(adapter);
              listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView parent, View view, int position, long id) {
                      Goods good=goodsList.get(position);
                      Toast.makeText(MainActivity.this,good.getName(),Toast.LENGTH_SHORT).show();
                  }
              });
      • 使用setOnItemClickListener()方法为ListView注册监听器,当用户点击了ListView中的任何一个子项,就会回调onItemClick()方法。
      • 通过使用Toast的makeText,其中第二个参数即为点击时显示的文本。

        Android Studio安卓开发--ListView学习整理,第4张

        4.对于ListView的界面优化

        我们可以发现此时的界面,文字字体太小,同时图片占据上方所有空间,不能使文字在紧靠在图片右侧呈现。修改方案如下:

        (1)新建xml文件来设置ImageView和TextView:

        
        
            
            
        
        • 设置为水平线性布局。
        • 将文本的layout_marginLeft的设置去除,使其自然水平布局。
        • 字体使用textSize进行设置大小。
        • 为什么要单独创一个xml文件?
        • 因为在总的xml文件中(如上的activity_main.xml)设置了ListView的布局为match_parent,会把界面都占满,导致在ListView上的图片也会把界面占满,右侧已没有空间放置文字,故要单独分离开。

          (2)将MainActivity中的adapter布局来源进行修改(修改为新建的xml)

          GoodsAdapter adapter=new GoodsAdapter(MainActivity.this,R.layout.abc,goodsList);

          (3)效果如下:

          Android Studio安卓开发--ListView学习整理,第5张

          5.提升ListView的运行效率

          前面已经说了,通过converView可以提升效率,不过这个虽然现在不会再重复去加载布局,但是每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例。可以借助一个ViewHolder(自定义)来对这部分性能进行优化。

          (1)修改GoodsAdapter中的代码:

              @Override
               public View getView(int position, View convertView, ViewGroup parent) {
                  Goods good = getItem(position);
                  View view;
                  ViewHolder viewHolder;
                  if(convertView==null)
                  {
                      view=LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
                      viewHolder = new ViewHolder();
                      viewHolder.goodImage=(ImageView) view.findViewById(R.id.goods_image);
                      viewHolder.goodName=(TextView)view.findViewById(R.id.goods_name);
                  }
                  else {
                      view=convertView;
                      viewHolder =(ViewHolder) view.getTag();
                  }
                  viewHolder.goodImage.setImageResource(good.getImageId());
                  viewHolder.goodName.setText(good.getName());
                  return view;
              }
              class ViewHolder{
                  ImageView goodImage;
                  TextView goodName;
              }
          • 新增ViewHolder内部类,用于对控件的实例进行缓存。
          • 当converView为null时,创建ViewHolder对象,并将控件的实例都存放在ViewHolder里,然后调用View的setTag()方法,将ViewHolder对象存储在View中。
          • 当converView不为null时,则调用View的setTag()方法,把ViewHolder重新取出(注意类型转换)。
          • 这样所有控件的实例都缓存在ViewHolder里,就没有必要每次都通过findViewById()方法来获取控件实例了。

            (上述学习内容来自《第一行代码 Android》第二版 郭霖著)

网友评论

搜索
最新文章
热门文章
热门标签
 
 梦见上坟烧纸火很旺  杀马特团长你就是歌姬吧  梦见地上有雪