运行环境
Android Studio 2020.3.1
1. ListView 与 Spinner组件
1.1 ListView 列表视图 Demo4
Android官网关于ListView的帮助文档:>>传送门<<
通过上图可以观察到ListView
是View
的间接子类。
ListView
主要用于显示可垂直
滚动的视图集合,其中每个视图都位于列表中上一个视图的正下方。
ListView
是一个未知详细信息的Adapter View
,比如类型和内容等信息。
ListView
根据需要从List Adapter
请求视图,例如在用户上下滚动时显示新视图。
(其中Adapter可以使用Android自带的比如ArrayAdapter、SimpleAdapter,除此之外也可以使用继承的类)
范例:继承BaseAdapter类实现MyAdapter
代码模板:
private class MyAdapter extends BaseAdapter {
// override other abstract methods here
@Override
public View getView(int position, View convertView, ViewGroup container) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.list_item, container, false);
}
((TextView) convertView.findViewById(android.R.id.text1))
.setText(getItem(position));
return convertView;
}
}
ListView还有许多方法,这里只是简单入门,想知道更多请参考上面官网的帮助文档。
1.2 Spinner 下拉列表 Demo1
参考资料:>>传送门<<
Spinner
是一次显示一个子对象并允许用户在其中进行选择的视图。微调器中的项目来自与此视图关联的适配器。
Spinner
内的项目来源于其Adapter
相关的View
1.3 ListView与Spinner的区别
相同点
- 都是
View
的间接子类 - 都是展示一组数据的组件
- 都可以使用继承的Adapter类
不同点
- ListView的项目会直接显示出来,而Spinner则是归纳到同一个组件,类似按钮,需要点击后才会显示所有的项目。
- ListView适合购物商品、视频课程等这类的布局,而Spinner适合表单的填写,比如选择所在地区。
2. 对象转换
2.1 将XML配置文件的内容转化为Java对象 Demo2
比如获取string类型的数据
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<array name="testColors">
<item>#f00</item>
<item>#0f0</item>
<item>#00f</item>
</array>
<string-array name="testColorNames">
<item>Red</item>
<item>Green</item>
<item>Blue</item>
</string-array>
</resources>
Resources resources = getResources();
String[] colorNames = resources.getStringArray(R.array.testColorNames);
2.2 将组件转化为Java对象
方法:findViewById(R.id.xxx)
范例:Button button = findViewById(R.id.myButton);
3. TypedArray
参考资料:>>传送门<<
官方解释:
Container for an array of values that were retrieved with Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int) or Resources#obtainAttributes. Be sure to call recycle() when done with them. The indices used to retrieve values from this structure correspond to the positions of the attributes given to obtainStyledAttributes.
意思大概就是该对象用来读取XML文件里的配置,比如通过Java代码去控制APP里某个组件的字体大小等。
3.1 创建对象
dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="testDimens">
<item>12sp</item>
<item>16sp</item>
<item>20sp</item>
</array>
<string-array name="testDimenNames">
<item>Small</item>
<item>Medium</item>
<item>Big</item>
</string-array>
</resources>
Resources resources = getResources();
String[] dimenNames= resources.getStringArray(R.array.testDimenNames);
TypedArray dimens = resources.obtainTypedArray(R.array.testDimens);
3.2 常用方法
范例:获取字体大小的属性
float dim = dimens.getDimension(i, 10.0f);
4. 监听事件
4.1 Spinner 监听事件
下拉列表选择第 i 个项时的监听事件:Demo1
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_single_choice, cities);
sp.setAdapter(adapter);
sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String city = cities[i];
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
4.2 ListView 监听事件
当列表的某个项被单击时
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
4.3 ImageView 监听事件
图片被单击时
iv_call.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "图片被单击!",Toast.LENGTH_LONG).show();
}
});
5. Adapter
参考资料:>>传送门<<
- Adapter是将数据绑定到UI界面上的桥接类。
- Adapter负责创建显示每个项目的子View和提供对下层数据的访问。
- Adapter充当Adapter View和该视图的基础数据之间的桥梁。
- Adapter负责为数据集中的每个项目生成android.view.View。
5.1 ArrayAdapter Demo1
参考资料:>>传送门<<
构造方法:
范例:创建一个ArrayAdapter对象
String[] cities = resources.getStringArray(R.array.cities);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_single_choice, cities);
官方对ArrayAdapter的解释:
You can use this adapter to provide views for an AdapterView, Returns a view for each object in a collection of data objects you provide, and can be used with list-based user interface widgets such as ListView or Spinner.
By default, the array adapter creates a view by calling Object#toString() on each data object in the collection you provide, and places the result in a TextView. You may also customize(定制) what type of view is used for the data object in the collection. To customize what type of view is used for the data object, override getView(int, android.view.View, android.view.ViewGroup) and inflate a view resource.
大概意思是说Adapter可以用来提供视图,并且可以与基于列表的用户界面小部件(如ListView或Spinner)一起使用。则有:
spinner.setAdapter(myArrayAdapter);
ListView.setAdapter(myArrayAdapter);
如果要使用自定义的ArrapAdapter的话,需要继承该类并重写getView(int, android.view.View, android.view.ViewGroup)
方法。
5.2 SimpleAdapter Demo5
参考资料:>>传送门<<
SimpleAdapter
是将静态数据映射到XML文件中定义的视图的简单适配器。- 可以将支持列表的数据指定为map的ArrayList。
- ArrayList中的每个条目对应于列表中的一行。
-
You also specify an XML file that defines the views used to display the row, and a mapping from keys in the Map to specific views.
- 上面这句来自官方的解释,意思是可以指定定义用于显示行的视图的XML文件,以及从映射中的键到特定视图的映射。即相当于不同布局的嵌套使用比如:
类似于通讯录的界面,每一个联系人都有图像 + 名称 + 电话号码 + 呼叫按钮的布局,而所有的联系人又在同一个ListView组件中。
构造方法:
范例:创建 SimpleAdapter对象
String[] names = new String[] {
"周星驰", "彭于晏", "买瓜的强子"};
String []phones = new String[] {
"666", "520", "999"};
int [] picIds = new int [] {
R.drawable.zhouxingchi, R.drawable.pengyuyan, R.drawable.liuhuaqiang};
ArrayList<HashMap<String, Object>> list = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put(KEY_NAME, names[i]);
hashMap.put(KEY_PHONE, phones[i]);
hashMap.put(KEY_PIC_ID, picIds[i]);
list.add(hashMap);
}
SimpleAdapter adapter = new SimpleAdapter(
this,
list,
R.layout.row_view,
new String[] {
KEY_NAME, KEY_PHONE, KEY_PIC_ID},
new int []{
R.id.row_view_tv_name, R.id.row_view_tv_phone, R.id.row_view_iv});
5.3 ArrayAdapter 与 SimpleAdapter 比较
相同点:
- 都可用作组件的Adapter适配器
- 都支持多元素的容器
不同点:
- ArrayAdapter通常是存储数组型数据如List、Array等,而SimpleAdapter则用HashMap型数据
5.4 继承Adapter类的代码框架
以继承ArrayAdapter类为例:
public class PictureAdapter extends ArrayAdapter<Picture> {
private Context context;
private ArrayList<Picture> list;
public PictureAdapter(@NonNull Context context, ArrayList<Picture> list) {
super(context, android.R.layout.simple_list_item_1, list);
this.context = context;
this.list = list;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v;
if(convertView == null){
v = LayoutInflater.from(context).inflate(R.layout.row_view, null, false);
} else{
v = convertView;
}
ImageView iv = v.findViewById(R.id.row_view_iv);
TextView tv = v.findViewById(R.id.row_view_tv);
Picture picture = list.get(position);
iv.setImageResource(picture.getPicId());;
tv.setText(picture.getName());
return v;
}
}
6. Demo
6.1 实现一个可选择的列表框
实现效果
layout_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/tv_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
strings.xml
<resources>
<string name="app_name">test</string>
<string-array name="cities">
<item>Wenzhou</item>
<item>Hangzhou</item>
<item>Ningbo</item>
</string-array>
</resources>
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
Resources resources = getResources();
String[] cities = resources.getStringArray(R.array.cities);
TextView tv = findViewById(R.id.tv_result);
Spinner sp = findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_single_choice, cities);
sp.setAdapter(adapter);
sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String city = cities[i];
tv.setText(city);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
}
6.2 实现通过列表框修改文本的颜色
实现效果
layout_main.xml
<?xml version="1