UI组件-AdapterView及其子类

前言

只要自己变优秀了,其他的事情才会跟着好起来。

ListView组件

ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项。接下来介绍几种创建ListView的方法。

代码示例

使用数组创建ListView
listview.xml


    
    
    


arrays.xml


    
        西游记
        水浒传
        三国演义
        红楼梦
    


使用ArrayAdapter创建ListView
listview2.xml


    
    
    
    

array_item.xml


MainActivity.java
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview2);

        ListView list1 = (ListView) findViewById(R.id.list1);
        //定义一个数组
        String []books = new String[] {"三国演义","红楼梦","西游记","水浒传"};
        //将数组包装为ArrayAdapter
        ArrayAdapter adapter1 = new ArrayAdapter(this, R.layout.array_item, books);
        //为ListView设置Adapter
        list1.setAdapter(adapter1);

        ListView list2 = (ListView) findViewById(R.id.list2);
        //定义一个数组
        String []names = new String[] {"孙悟空","猪八戒","沙和尚","唐僧"};
        //将数组包装为ArrayAdapter
        ArrayAdapter adapter2 = new ArrayAdapter(this, R.layout.array_item, names);
        //为ListView设置Adapter
        list2.setAdapter(adapter2);
    }
}

使用SimpleAdapter创建ListView
listview3.xml、



    
    


simple_item.xml


    
    
    
        
        
         
         
    

MainActivity.java
public class MainActivity extends Activity {

    private String[] names = new String[]
            {"考拉","郁金香","企鹅","水母"};

    private String[] descs = new String[]
            {"一种可爱的动物","一种美丽的花朵","一种生活在南极的动物","一种生活在海里的神奇生物"};
    private int[] imageIds = new int[]
            {R.drawable.kaola,R.drawable.yujinx,R.drawable.qie,R.drawable.shuimo};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview3);
        //创建一个List集合,List集合的元素是Map
        List> listItems = new ArrayList>();
        for(int i = 0; i < names.length; i++)
        {
            Map listItem = new HashMap();
            listItem.put("header", imageIds[i]);
            listItem.put("name", names[i]);
            listItem.put("desc", descs[i]);
            listItems.add(listItem);
        }
        //创建一个SimpleAdapter
        SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.simple_item,
                new String[] {"name","header","desc"},
                new int[] {R.id.name,R.id.header,R.id.desc});

        ListView list = (ListView) findViewById(R.id.mylist);
        //为ListView设置Adapter
        list.setAdapter(simpleAdapter);
    }
}


使用BaseAdapter创建ListView
listview4.xml


    


MainActivity.java
public class MainActivity extends Activity {
    ListView myList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview4);

        myList = (ListView) findViewById(R.id.myList);
        BaseAdapter adapter = new BaseAdapter() {

            //重写该方法,该方法返回的View将作为列表框
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                //创建一个LinearLayout,并向其中添加两个组件
                LinearLayout line = new LinearLayout(MainActivity.this);
                line.setOrientation(0);
                ImageView image = new ImageView(MainActivity.this);
                image.setImageResource(R.drawable.ic_launcher);
                TextView text = new TextView(MainActivity.this);
                text.setText("第" + (position + 1) + "个列表项");
                text.setTextSize(20);
                text.setTextColor(Color.RED);
                line.addView(image);
                line.addView(text);
                return line;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public Object getItem(int position) {
                return null;
            }

            @Override
            public int getCount() {
                //指定一共包含40个列表项
                return 40;
            }
        };
        myList.setAdapter(adapter);
    }
}

基于ListActivity实现列表
listactivity.xml



MainActivity.java
public class MainActivity extends ListActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //无需使用布局文件
        String[] names = {"西游记","红楼梦","三国演义","水浒传"};
        //创建ArrayAdapter对象
        ArrayAdapter adapter = new ArrayAdapter(this, R.layout.listactivity, names);
        //设置该窗口显示列表
        setListAdapter(adapter);
    }
}

效果

使用数组创建的ListView

UI组件-AdapterView及其子类_第1张图片
Screenshot_1508382099.png

使用ArrayAdapter创建的ListView

UI组件-AdapterView及其子类_第2张图片
Screenshot_1508383040.png

使用SimpleAdapter创建的ListView

UI组件-AdapterView及其子类_第3张图片
Screenshot_1508388930.png

使用BaseAdapter创建的ListView

UI组件-AdapterView及其子类_第4张图片
Screenshot_1508389647.png

基于ListActivity实现的列表

UI组件-AdapterView及其子类_第5张图片
Screenshot_1508390424.png

提示

当列表项很多时,为了防止内存溢出,可以使用ListView的andriod:scrollingCache属性来绘制缓冲,同时还有别的方法。以后将会介绍。
下面我来说说上述几个Adapter的区别。
  • ArrayAdapter:简单、易用的Adapter,通常用于将数组或List集合的多个值包装成多个列表项。

  • SimpleAdapter:并不简单、功能强大的Adapter,可用于将List集合的多个对象包装成多个列表项。

  • BaseAdapter:通常用于被扩展。扩展BaseAdapter可以对各列表项进行最大限度的定制。我比较喜欢用这个Adapter,使用这个Adapter需要重写如下四个方法。

    1. getCount():该方法的返回值控制该Adapter将会包含多少个列表项。

    2. getItem(int position):该方法的返回值决定第position处的列表项的内容。

    3. getItemId(int position):该方法的返回值决定第position处的列表项的ID。

    4. getView(int position,View convertView,ViewGroup parent):该方法的返回值决定第position处的列表项组件。

其中最重要的第1个和第4个方法。

AutoCompleteTextView组件

自动完成文本框(AutoCompeletTextView)从EditText派生而出,实际上它也是一个文本编辑框,但它比普通编辑框多了一个功能:当用户输入一定的字符之后,自动完成文本框会显示一个下拉菜单,供用户选择,当用户选择某个菜单项之后,AutoCompleteTextView按用户选择自动填写该文本框。

代码示例

autocompletetextview.xml


    
    
    
    

MainActivity.java
public class MainActivity extends Activity {
    AutoCompleteTextView actv;
    MultiAutoCompleteTextView mauto;
    //定义字符串数组,作为提示文本
    String[] books = new String[] {
            "西游记",
            "水浒传",
            "三国演义",
            "水浒传"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.autocompletetextview);
        //创建一个ArrayAdapter,封装数组
        ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, books);
        actv = (AutoCompleteTextView) findViewById(R.id.auto);
        //设置Adapter
        actv.setAdapter(adapter);
        mauto = (MultiAutoCompleteTextView) findViewById(R.id.mauto);
        //设置Adapter
        mauto.setAdapter(adapter);
        //为MultiAutoCompleteTextView设置分隔符
        mauto.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
    }
}

效果

UI组件-AdapterView及其子类_第6张图片
Screenshot_1508393517.png

提示

AutoCompleteTextView与MultiAutoCompleteTextView的区别在于MultiAutoCompleteTextView允许输入多个提示项,多个提示项以分隔符分隔。
android:comletionThreshold属性,设置用户至少输入几个字符才会显示提示。

GridView组件

网格视图(GridView)和ListView有共同的父类,它们的唯一区别在于ListView只显示一列,而GridView可以显示多列。另外,ListView相当于一种特殊的GridView,如果GridView只显示一列,那么该GridView就变成了ListView。
与ListView类似的是,GridView也需要Adapter来提供显示的诗数据,可以通过ArrayAdapter、SimpleAdapter、BaseAdapter来创建Adapter,用法基本一致。

代码示例

gridview.xml


    
    
    
    

cell.xml



MainActivity.java
public class MainActivity extends Activity {

    GridView grid;
    ImageView imageView;
    int[] imageIds = new int[]
            {
                R.drawable.baxianhua,R.drawable.dengta,R.drawable.ic_launcher,R.drawable.juhua,
                R.drawable.kaola,R.drawable.shamo,R.drawable.shuimo,R.drawable.yujinx,
                R.drawable.qie,R.drawable.shamo,R.drawable.shuimo,R.drawable.yujinx,
                R.drawable.baxianhua,R.drawable.dengta,R.drawable.ic_launcher,R.drawable.juhua
            };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gridview);

        //创建一个List对象,List对象的元素是Map
        List> listItems = new ArrayList>();
        for (int i = 0; i < imageIds.length; i++) {
            Map listItem = new HashMap();
            listItem.put("image", imageIds[i]);
            listItems.add(listItem);
        }
        //获取显示图片的ImageView
        imageView = (ImageView) findViewById(R.id.imageView);
        //创建一个SimpleAdapter
        SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.cell,
                new String[] {"image"}, new int[] {R.id.image1});
        grid = (GridView) findViewById(R.id.grid01);
        //为GridView设置Adapter
        grid.setAdapter(simpleAdapter);
        //添加列表项被选中的监听器
        grid.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onNothingSelected(AdapterView parent) {
            }

            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                //显示当前被选中的图片
                imageView.setImageResource(imageIds[position]);
            }
        });

        //添加列表项被单击的监听器
        grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                //显示背单击的图片
                imageView.setImageResource(imageIds[position]);
            }
        });
    }
}

效果

UI组件-AdapterView及其子类_第7张图片
Screenshot_1508398206.png

提示

android:numColumns属性,设置列数。
android:horizontalSpacing属性,设置个元素之间的水平间距。
android:verticalSpacing属性,设置个元素之间的垂直间距。

ExpandableListView组件

可展开的列表组件(ExpandableListView)是ListView的子类,它在普通ListView的基础上进行了扩展,它把应用中的列表项分为几组,每组里又可包含多个列表项。
ExpandableListView所显示的列表项由ExpandableListAdapter提供。实现ExpandableListAdapter的方式有如下三种。
  • 扩展BaseExpandableListAdapter实现ExpandableListAdapter。

  • 使用SimpleExpandableListAdapter将两个List集合包装成ExpandableListAdapter。

  • 使用SimpleCursorTreeAdapter将Cursor中的数据包装成SimpleCursorTreeAdapter。

代码示例

expandablelistview.xml


    


MainActivity.java
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.expandablelistview);
        //创建一个ExpandableListAdapter对象
        ExpandableListAdapter adapter = new BaseExpandableListAdapter() {

            int[] logos = new int[]
            {
                R.drawable.kaola,
                R.drawable.qie,
                R.drawable.shuimo
            };

            private String[] armTypes = new String[]
            {"考拉","企鹅","水母"};
            private String[][] arms = new String[][]
            {
                {"白考拉","红考拉","黑考拉"},
                {"白企鹅","帝企鹅","黑企鹅"},
                {"白水母","毒水母","黑水母"}
            };

            @Override
            public boolean isChildSelectable(int groupPosition, int childPosition) {
                return true;
            }

            @Override
            public boolean hasStableIds() {
                return true;
            }

            //该方法决定每个组选项的外观
            @Override
            public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
                LinearLayout ll = new LinearLayout(MainActivity.this);
                ll.setOrientation(0);
                ImageView logo = new ImageView(MainActivity.this);
                logo.setImageResource(logos[groupPosition]);
                logo.setLayoutParams(new LinearLayout.LayoutParams(100, 100));
                ll.addView(logo);
                TextView textView = new TextView(MainActivity.this);
                textView.setText(getGroup(groupPosition).toString());
                textView.setTextSize(20);
                ll.addView(textView);
                return ll;
            }

            @Override
            public long getGroupId(int groupPosition) {
                return groupPosition;
            }

            @Override
            public int getGroupCount() {
                return armTypes.length;
            }

            //获取指定组位置处的组数据
            @Override
            public Object getGroup(int groupPosition) {
                return armTypes[groupPosition];
            }

            @Override
            public int getChildrenCount(int groupPosition) {
                return arms[groupPosition].length;
            }

            private TextView geTextView()
            {
                AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,64);
                TextView textView = new TextView(MainActivity.this);
                textView.setLayoutParams(lp);
                textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
                textView.setPadding(36, 0, 0, 0);
                textView.setTextSize(20);
                return textView;
            }
            //该方法决定每个子选项的外观
            @Override
            public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
                    ViewGroup parent) {
                TextView textView = geTextView();
                textView.setText(getChild(groupPosition, childPosition).toString());
                return textView;
            }

            @Override
            public long getChildId(int groupPosition, int childPosition) {
                return childPosition;
            }

            //获取指定组位置、指定子列表项处的子列表项数据
            @Override
            public Object getChild(int groupPosition, int childPosition) {
                return arms[groupPosition][childPosition];
            }
        };
        ExpandableListView expandListView = (ExpandableListView) findViewById(R.id.list);
        expandListView.setAdapter(adapter);
    }
}

效果

UI组件-AdapterView及其子类_第8张图片
Screenshot_20171020-093318.png

提示

上面使用BaseExpandableListAdapter来实现ExpandableListAdapter,当扩展BaseExpandableListAdapter时,关键是实现如下4个方法。
  • getGroupCount():该方法返回包含的组列表项的数量。

  • getGroupView():该方法返回的View对象将作为组列表项。

  • getChildrenCount():该方法返回特定组所包含的子列表项的数量。

  • getChildView():该方法返回的View对象将作为特定组,特定位置的子列表项。


Spinner组件

Spinner其实就是一个列表选择框,不过不是显示下拉列表,而是弹出一个菜单供用户选择。如果已经确定了Spinner的列表项,只要为Spinner指定android:entries属性即可;如果不确定列表项,需要在程序运行时动态决定Spinner的列表项,则需要用Adapter来为Spinner提供列表项。

代码示例

spinner.xml


    
    
    

MainActivity.java
public class MainActivity extends Activity {
    Spinner spinner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.spinner);
        //获取界面布局文件中的Spinner
        spinner = (Spinner) findViewById(R.id.spinner);
        String []arr = {"西游记","红楼梦","三国演义","水浒传"};
        //创建ArrayAdapter对象
        ArrayAdapter adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_multiple_choice,arr);
        //为Spinner设置Adapter
        spinner.setAdapter(adapter);
    }
}

效果

UI组件-AdapterView及其子类_第9张图片
Screenshot_20171020-100344.png

提示

第一个Spinner组件指定了android:entries属性,第二个Spinner组件没有指定android:entries属性,因此需要在Activity中为它设置Adapter。

AdapterViewFlipper组件

AdapterViewFlipper继承了AdapterViewAnimator,它也会显示Adapter提供的多个View组件,但它每次只能显示一个View组件,程序可通过showPrevious()和showNext()方法控制该组件显示上一个、下一个组件。它还有自动播放的功能。

代码示例

adapterviewanimator.xml


    
    
MainAvtivity.java
public class MainActivity extends Activity {

    int[] imageIds = new int[]
    {
        R.drawable.baxianhua,R.drawable.dengta,R.drawable.juhua,
        R.drawable.kaola,R.drawable.qie,R.drawable.shamo,R.drawable.shuimo,
        R.drawable.yujinx
    };
    private AdapterViewFlipper flipper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.adapterviewanimator);
        flipper = (AdapterViewFlipper) findViewById(R.id.flipper);
        //创建一个BaseAdapter对象
        BaseAdapter adapter = new BaseAdapter() {

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {

                //创建一个ImageView
                ImageView imageView = new ImageView(MainActivity.this);
                imageView.setImageResource(imageIds[position]);
                //设置ImageView的缩放类型
                imageView.setScaleType(ScaleType.FIT_XY);
                //为ImageView设置布局参数
                imageView.setLayoutParams(new ViewGroup.LayoutParams(
                        LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT
                        ));
                return imageView;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public Object getItem(int position) {
                return imageIds[position];
            }

            @Override
            public int getCount() {
                return imageIds.length;
            }
        };
        flipper.setAdapter(adapter);
    }

    public void prev(View view) {
        //显示上一个组件
        flipper.showPrevious();
        //停止自动播放
        flipper.stopFlipping();
    }

    public void next(View view) {
        //显示上一个组件
        flipper.showNext();
        //停止自动播放
        flipper.stopFlipping();
    }

    public void auto(View view) {
        //开始自动播放
        flipper.startFlipping();
    }
}

效果

UI组件-AdapterView及其子类_第10张图片
Screenshot_20171020-103243.png

提示

android:animateFirstView属性,设置显示该组件的第一个View时是否使用动画。
android:inAnimation属性,设置组件显示时使用的动画。
android:loopViews属性,设置循环播放。
android:autoStart属性,设置是否自动播放。
android:flipInterval属性,设置自动播放的时间间隔。

StackView组件

StackView也是AdapterViewAnimator的子类,它用于显示Adapter提供的一系列View。StackView将会以“堆叠”的方式来显示多个列表项。

代码示例

stackview.xml


    
    
        
MainActivity.java
public class MainActivity extends Activity {

    private StackView stackView;

    int[] imageIds = new int[]
    {
        R.drawable.baxianhua,R.drawable.dengta,R.drawable.juhua,
        R.drawable.kaola,R.drawable.qie,R.drawable.shamo,R.drawable.shuimo,
        R.drawable.yujinx
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stackview);
        stackView = (StackView) findViewById(R.id.stackview);
        //创建一个List对象,List对象的元素是Map
        List> listItems = new ArrayList>();
        for (int i = 0; i < imageIds.length; i++) {
            Map listItem = new HashMap();
            listItem.put("image", imageIds[i]);
            listItems.add(listItem);
        }
        //创建一个SimpleAdapter
        SimpleAdapter simpleAdapter = new SimpleAdapter(this,
                listItems, R.layout.cell, new String[] {"image"}, new int[] {R.id.image1});

        stackView.setAdapter(simpleAdapter);
    }

    public void prev(View view) {
        //显示上一个组件
        stackView.showPrevious();
    }
    public void next(View view) {
        //显示下一个组件
        stackView.showNext();
    }
}

效果

UI组件-AdapterView及其子类_第11张图片
Screenshot_20171020-110029.png

你可能感兴趣的:(UI组件-AdapterView及其子类)