<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:paddingTop="15dp"
android:paddingBottom="10dp">
<Spinner
android:id="@+id/area"
android:theme="@style/TabLayoutTabStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown">Spinner>
<Spinner
android:id="@+id/town"
style="?android:spinnerItemStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown">Spinner>
<Spinner
android:id="@+id/village"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:spinnerMode="dropdown">Spinner>
LinearLayout>
做完第一步显示效果仅仅是三个箭头而已,内容是空,需要为它设置包含内容的TextView.写在spinner_item.xml内
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_view"
android:text="test"
android:textSize="13sp"
android:textColor="@color/spinnerText"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
LinearLayout>
基于前面的分析,适配器的绑定数据肯定要用到封装类,所以先把这事办了:
package com.sdxzt.xueliangapp_v2.video_monitor_page;
/**
* 封装区域对象,三种属性,名字/自身id/父级区域id
*/
public class SpinnerBean {
private String name;
private int id;
private int parentId;
public SpinnerBean(String name, int id, int parentId) {
this.name = name;
this.id = id;
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
}
在进入正题前,先列举一下这个类的方法,这些方法大多是回调函数,因为会用到,而又不熟悉.总结一下
看了上面的方法作用自然就明白了,getView和getDropDownView是分别针对打开和未打开的列表,对样式的设置,自然在这两个方法里.
首行显示红色,只需在getView里为TextView控件设置颜色即可
打开后,已选择的条目显示红色,这里就需要在绘制每个条目时判断这个position是否被选中,那么就要定义一个变量,判断它和当前position是否相等.这个变量的值可以spinner的OnItemSelected监听器触发时传进来.
SpinnerAdapter.java
package com.sdxzt.xueliangapp_v2.video_monitor_page;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.sdxzt.xueliangapp_v2.R;
import java.util.ArrayList;
/**
* 地区选择下拉列表的适配器,主要是apapter使数据绑定到控件变得更加简单和灵活...用途为容器提供子视图,利用视图的数据和元数据来构建每个子视图。
*/
public class SpinnerAdapter extends BaseAdapter {
private Context context;
private ArrayList<SpinnerBean> list;
int selectedPosition;
public SpinnerAdapter(Context context, ArrayList<SpinnerBean> list,int parentId) {
Log.d("SpinnerAdapter", "list初始化完成"+list.size());
this.context = context;
this.list = new ArrayList<>();
//把应该显示的地区提取到新集合中
this.list.add(new SpinnerBean("请选择", -1, -1));
for (SpinnerBean item:list) {
if (item.getParentId() == parentId) {
this.list.add(item);
}
}
Log.d("全部list的元素:" + list.size(), "当前list的元素:" + this.list.size());
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
/**
* 这个是下拉前的布局
* @param i 位置
* @param view 列表单项的视图
* @param viewGroup
* @return
*/
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder = null;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.spinner_item,viewGroup,false);
viewHolder = new ViewHolder();
viewHolder.textView = view.findViewById(R.id.text_view);
//用来绑定控件信息,以便复用,不需要每次查找赋值.主要场景是当控件超出屏幕范围消失,再次出现时复用
view.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) view.getTag();
}
//绑定数据
viewHolder.textView.setText(list.get(i).getName());
//这里的颜色仅限选择列表首行显示的内容
viewHolder.textView.setTextColor(Color.RED);
return view;
}
/**
* 这是下拉后,下拉的布局
* @param position
* @param convertView
* @param parent
* @return
*/
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
//修改Spinner展开后的字体颜色
ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.spinner_item,parent,false);
viewHolder = new ViewHolder();
viewHolder.textView = convertView.findViewById(R.id.text_view);
//用来绑定控件信息,以便复用,不需要每次查找赋值.主要场景是当控件超出屏幕范围消失,再次出现时复用
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
//默认显示文字的TextView
TextView textView = convertView.findViewById(R.id.text_view);
textView.setTextColor(Color.BLACK);
//根据点击位置改变颜色
if (position == selectedPosition) {
textView.setTextColor(Color.RED);
}
viewHolder.textView.setText(list.get(position).getName());
return convertView;
}
/**
* 当spinner的OnItemSelected监听器触发时,调用该方法,把选中的位置作为参数传进来,用于在绘制时
* 判断当前条目是否被选中,应该是什么颜色
* @param selectedPosition
*/
public void setSelectedPosition(int selectedPosition) {
this.selectedPosition = selectedPosition;
}
public class ViewHolder{
TextView textView;
}
}
监听器要做的事:
//区spinner的监听器
private class AreaClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
areaSpinnerAdapter.setSelectedPosition(i);
SpinnerBean item = (SpinnerBean) adapterView.getItemAtPosition(i);
//把该选项的id作为参数,为下一级设置适配器
townSpinnerAdapter = new SpinnerAdapter(VideoMonitorActivity.this, townList, item.getId());
town.setAdapter(townSpinnerAdapter);
if ("请选择".equals(item.getName())) {
Log.d("onItemSelected", "低级列表设置不可见");
town.setVisibility(View.INVISIBLE);
village.setVisibility(View.INVISIBLE);
} else {
town.setVisibility(View.VISIBLE);
town.setSelection(0);
}
//TODO 自定义一个弹框工具类
Toast.makeText(getApplicationContext(), item.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
//镇的监听器
private class TownClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
townSpinnerAdapter.setSelectedPosition(i);
SpinnerBean item = (SpinnerBean) adapterView.getItemAtPosition(i);
villageSpinnerAdapter = new SpinnerAdapter(VideoMonitorActivity.this, villageList, item.getId());
village.setAdapter(villageSpinnerAdapter);
if ("请选择".equals(item.getName())) {
village.setVisibility(View.INVISIBLE);
} else {
village.setVisibility(View.VISIBLE);
village.setSelection(0);
}
Toast.makeText(getApplicationContext(), item.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
//村的监听器
private class VillageClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
villageSpinnerAdapter.setSelectedPosition(i);
SpinnerBean item = (SpinnerBean) adapterView.getItemAtPosition(i);
Toast.makeText(getApplicationContext(), item.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
package com.sdxzt.xueliangapp_v2.video_monitor_page;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SnapHelper;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.Spinner;
import android.widget.Toast;
import com.sdxzt.xueliangapp_v2.R;
import com.sdxzt.xueliangapp_v2.base.HeadFragment;
import java.util.ArrayList;
/**
* 视频监控页面,包括头部,区域选择列表,视频网格列表
*/
public class VideoMonitorActivity extends AppCompatActivity {
private Spinner area, town, village;
private ArrayList<SpinnerBean> areaList;
private ArrayList<SpinnerBean> townList;
private ArrayList<SpinnerBean> villageList;
private SpinnerAdapter townSpinnerAdapter,areaSpinnerAdapter,villageSpinnerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_monitor);
initView();
//添加列表全部地区
loadArea();
loadTown();
loadVillage();
//给第一级列表添加适配器,父级元素id固定为0,所以可以这这里设置
areaSpinnerAdapter = new SpinnerAdapter(this, areaList, 0);
area.setAdapter(areaSpinnerAdapter);
//设置选择监听器
area.setOnItemSelectedListener(new AreaClickListener());
town.setOnItemSelectedListener(new TownClickListener());
village.setOnItemSelectedListener(new VillageClickListener());
}
private void loadArea() {
areaList = new ArrayList<>();
areaList.add(new SpinnerBean("请选择", -1, -1));
areaList.add(new SpinnerBean("兖州区", 1, 0));
areaList.add(new SpinnerBean("任城区", 2, 0));
areaList.add(new SpinnerBean("市中区", 3, 0));
}
private void loadTown() {
townList = new ArrayList<>();
townList.add(new SpinnerBean("请选择", -1, -1));
townList.add(new SpinnerBean("新驿镇", 101, 1));
townList.add(new SpinnerBean("小孟镇", 102, 1));
townList.add(new SpinnerBean("新兖镇", 103, 1));
townList.add(new SpinnerBean("李营街道", 104, 2));
townList.add(new SpinnerBean("仙营街道", 103, 2));
townList.add(new SpinnerBean("市中区1号", 105, 3));
townList.add(new SpinnerBean("市中区2号", 106, 3));
//因为需要根据父级联动,所以要在父级选定后设置适配器
//town.setAdapter(new SpinnerAdapter(this,townList));
}
private void loadVillage() {
villageList = new ArrayList<>();
villageList.add(new SpinnerBean("请选择", -1, -1));
villageList.add(new SpinnerBean("一村", 200, 101));
villageList.add(new SpinnerBean("二村", 201, 101));
villageList.add(new SpinnerBean("三村", 202, 101));
villageList.add(new SpinnerBean("四村", 203, 101));
villageList.add(new SpinnerBean("五村", 204, 101));
int id = 205;
for (int i = 102; i < 106; i++) {
for (int j = 0; j < 3; j++) {
villageList.add(new SpinnerBean("村" + j, id++, i));
}
}
//village.setAdapter(new SpinnerAdapter(this,villageList));
}
private void initView() {
headContainer = findViewById(R.id.head_container);
area = findViewById(R.id.area);
town = findViewById(R.id.town);
village = findViewById(R.id.village);
videoContainer = findViewById(R.id.video_container);
}
//区spinner的监听器
private class AreaClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
areaSpinnerAdapter.setSelectedPosition(i);
SpinnerBean item = (SpinnerBean) adapterView.getItemAtPosition(i);
//把该选项的id作为参数,为下一级设置适配器
townSpinnerAdapter = new SpinnerAdapter(VideoMonitorActivity.this, townList, item.getId());
town.setAdapter(townSpinnerAdapter);
if ("请选择".equals(item.getName())) {
Log.d("onItemSelected", "低级列表设置不可见");
town.setVisibility(View.INVISIBLE);
village.setVisibility(View.INVISIBLE);
} else {
town.setVisibility(View.VISIBLE);
town.setSelection(0);
}
//TODO 自定义一个弹框工具类
Toast.makeText(getApplicationContext(), item.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
//镇的监听器
private class TownClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
townSpinnerAdapter.setSelectedPosition(i);
SpinnerBean item = (SpinnerBean) adapterView.getItemAtPosition(i);
villageSpinnerAdapter = new SpinnerAdapter(VideoMonitorActivity.this, villageList, item.getId());
village.setAdapter(villageSpinnerAdapter);
if ("请选择".equals(item.getName())) {
village.setVisibility(View.INVISIBLE);
} else {
village.setVisibility(View.VISIBLE);
village.setSelection(0);
}
Toast.makeText(getApplicationContext(), item.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
//村的监听器
private class VillageClickListener implements AdapterView.OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
villageSpinnerAdapter.setSelectedPosition(i);
SpinnerBean item = (SpinnerBean) adapterView.getItemAtPosition(i);
Toast.makeText(getApplicationContext(), item.getName(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
}