CheckBox (多选)
extends Button
checkBox中选择器
state_checked : 已经被选中了
state_checkable: 可以被选中
给checkBox设置选择器: (get新技能!!)
在设置之前我们先将选择器列上
1, 给android:button=”@drawable/cb_sel设置背景选择器
选择器
cb_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="2dp"/>
<stroke android:color="#000" android:width="2dp"/>
<size android:width="20dp" android:height="20dp"/>
</shape>
cb_bg_1.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="2dp"/>
<stroke android:color="#000" android:width="2dp"/>
<solid android:color="#f00"/>
<size android:width="20dp" android:height="20dp"/>
</shape>
cb_sel.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/cb_bg_1" android:state_checked="true" />
<item android:drawable="@drawable/cb_bg" />
</selector>
activity_main.xml
<CheckBox
android:button="@drawable/cb_sel"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
效果
选择事件
我们通过一个模拟点赞的例子, 来说明点击事件
首先来个颜色选择器
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#0f0" android:state_checked="true"/>
<!--设置为透明, 未选中时,透明色覆盖-->
<item android:color="#0000"/>
</selector>
activity_main.xml
注意, 需要将button置为空
并且将图片放在控件顶部
<!--
checked: 是否被选中
android:button="@drawable/cb_sel" 可以被替换掉
可是使用@null将原生控件去掉
-->
<CheckBox
android:layout_centerInParent="true"
android:id="@+id/main_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null"
android:checked="true"
android:drawableTop="@mipmap/ic_launcher"
android:text="复选框" />
给它着色, 可以使用 android:drawableTint=”@color/cb_color_sel”在xml中设置, 但是它是API23以后才可以使用 目前(2016-8-26)几乎不能用, 所以我们要找一个兼容的办法, 看MainActivity.java
MainActivity.java
CheckBox checkBox = (CheckBox) findViewById(R.id.main_cb);
//checkBox.setCompoundDrawableTintList();//API23之后可用
//获取到四周的drawable, 分为左上中下
Drawable[] drawables = checkBox.getCompoundDrawables();
//拿到顶部 顺序: 左上右下
Drawable top = drawables[1];
//top.setTint();最低版本21, 使用兼容包, 来兼容低版本手机
// 参数: 1, 给谁着色 2,获取颜色列表
ColorStateList list = getResources().getColorStateList(R.color.cb_color_sel);
DrawableCompat.setTintList(top,
list);
DrawableCompat.setTintMode(top, PorterDuff.Mode.SRC_ATOP);
//设置监听
checkBox.setOnCheckedChangeListener(this);
checkBox.setText("+" + count);
事件监听方法
//点击事件方法
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
buttonView.setText("+" + (count + (isChecked ? 1 : 0)));
}
效果图:
注意:
1, 一般情况下, 后面带有 ~Compat的, 为支持包;
2, checkBox.getCompoundDrawables();返回的是该控件在四周的drawable, 一个四个, 0 - 3 (包含) , 顺序是, 左上右下
Radio(单选)
我们用单选按钮来实现类似于微信底部的导航条
布局文件
<!--
RadioGroup
extents: LinerLayout
Radio中只能防止放置RadioButton
RadioButton
extents:CompoundButton
-->
<RadioGroup
android:id="@+id/main_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rb_0"
style="@style/radioStyle"
android:drawableTop="@android:drawable/ic_menu_send"
android:text="发送" />
<RadioButton
android:id="@+id/rb_1"
style="@style/radioStyle"
android:drawableTop="@android:drawable/ic_menu_camera"
android:text="相机" />
<RadioButton
android:id="@+id/rb_2"
style="@style/radioStyle"
android:drawableTop="@android:drawable/ic_menu_call"
android:text="电话" />
<RadioButton
android:id="@+id/rb_3"
style="@style/radioStyle"
android:drawableTop="@android:drawable/ic_menu_agenda"
android:text="日程" />
</RadioGroup>
style文件
<style name="radioStyle">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:gravity">center</item>
<item name="android:button">@null</item>
<item name="android:textColor">@color/cb_color_sel</item>
<!--<item name="android:drawableTint">@color/cb_color_sel</item>-->
<!--<item name="android:drawableTintMode">src_atop</item>-->
</style>
上述注释代码, API23才可以使用
Activity代码
//单选按钮 着色
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.main_group);
for (int i = 0; i < radioGroup.getChildCount(); i++) {
RadioButton button = (RadioButton) radioGroup.getChildAt(i);
Drawable drawable = button.getCompoundDrawables()[1];
DrawableCompat.setTintList(drawable, list);
DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_ATOP);
}
效果图
动态实现, 图片轮播下面的小点的实现
背景选择器
nav_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="10dp" android:height="10dp"/>
<solid android:color="#444"/>
</shape>
nav_bg_1.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="10dp" android:height="10dp"/>
<solid android:color="#ccc"/>
</shape>
nav_sel.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/nav_bg_1" />
<item android:drawable="@drawable/nav_bg" />
</selector>
main.xml 布局文件
<!--
需要动态实现, 小点
-->
<RadioGroup
android:layout_centerInParent="true"
android:orientation="horizontal"
android:id="@+id/main_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</RadioGroup>
Activity代码
LayoutInflater inflater = LayoutInflater.from(this);
navigation = (RadioGroup) findViewById(R.id.main_navigation);
for (int i = 0; i < 10; i++) {
// 第二个参数不要指定为空, 第三个,加不加载上, 如果写true就返回父控件, 否则返回
View radioButton = inflater.inflate(R.layout.radio_child, navigation, false);
radioButton.setId(i);
navigation.addView(radioButton);
}
navigation.check(0);
事件监听方法
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//点击上方图片实现
// 实现轮播
int i = navigation.getCheckedRadioButtonId();
i++;
if (i >= navigation.getChildCount()) {
i = 0;
}
navigation.check(i);
}
Spinner(下拉列表)
简单说一下适配器视图: AdapterView extens ViewGroup
它是负责将数据源未来该怎样显示在屏幕上
最简单的显示方式, 使用资源文件
strings.xml
<string-array name="test_data">
<item>Test 01</item>
<item>Test 02</item>
<item>Test 03</item>
<item>Test 04</item>
<item>Test 05</item>
</string-array>
main.xml
<!--
popupBackground: 弹出框的背景颜色
-->
<Spinner
android:layout_centerInParent="true"
android:entries="@array/test_data"
android:layout_width="wrap_content"
android:popupBackground="#fff"
android:layout_height="wrap_content"/>
效果图
该种方式, 局限太大, 使用频率较小
View绝对不能直接操作数据源, 数据源永远是通过控制器来操作
下拉列表联动 对Spinner有个深入的了解
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="数据: "
android:textSize="30sp"
android:textColor="#00f"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!--
android:id="@android:id/text1" : 使用系统id
-->
<TextView
android:id="@+id/item_text"
android:textSize="30sp"
android:textColor="#000"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.lulu.day22_spinner.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<!--
popupBackground: 弹出框的背景颜色
-->
<Spinner
android:background="#f00"
android:id="@+id/main_spinner"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:popupBackground="#fff" />
<!--
popupBackground: 弹出框的背景颜色
-->
<Spinner
android:background="#0f0"
android:id="@+id/main_spinner_1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:popupBackground="#fff" />
<!--
popupBackground: 弹出框的背景颜色
-->
<Spinner
android:background="#00f"
android:id="@+id/main_spinner_2"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:popupBackground="#fff" />
</LinearLayout>
</RelativeLayout>
Activity代码
/**
* 下拉列表
*/
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private ArrayAdapter<String> adapter;
private ArrayAdapter<String> adapter_1;
private ArrayAdapter<String> adapter_2;
private static final String[] PROVINCES = {"北京", "河北", "山东"};
private static final String[][] CITIES = {{"北京"}, {"石家庄", "邯郸", "衡水", "张家口"}, {"济南", "泰安", "青岛", "日照"}};
private static final String[][][] AREAS = { { {"海淀", "昌平", "朝阳", "东城", "西城"} }, {{"A", "B"}, {"C", "D"}, {} , {} }, { {}, {}, {}, {} } };
private Spinner spinner;
private Spinner spinner_1;
private Spinner spinner_2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner = (Spinner) findViewById(R.id.main_spinner);
spinner_1 = (Spinner) findViewById(R.id.main_spinner_1);
spinner_2 = (Spinner) findViewById(R.id.main_spinner_2);
// 上下文对象(主要用来创建View, 只要你想创建任何View, 都需要上下文对象) 视图 数据源
adapter = new ArrayAdapter<>(this,R.layout.spinner_child,R.id.item_text, new ArrayList(Arrays.asList(PROVINCES)));
adapter_1 = new ArrayAdapter<>(this,R.layout.spinner_child,R.id.item_text, new ArrayList(Arrays.asList(CITIES[0])));
adapter_2 = new ArrayAdapter<>(this,R.layout.spinner_child,R.id.item_text, new ArrayList(Arrays.asList(AREAS[0][0])));
spinner.setAdapter(adapter);
spinner_1.setAdapter(adapter_1);
spinner_2.setAdapter(adapter_2);
// findViewById(R.id.main_add).setOnClickListener(this);
//不让开发者调用, 直接抛出异常
// spinner.setOnItemClickListener();
spinner.setOnItemSelectedListener(this);
spinner_1.setOnItemSelectedListener(this);
spinner_2.setOnItemSelectedListener(this);
}
/*****************************/
//选中时调用
@Override //对应的spinner 哪个View被选中了 位置 ArrayAdapter中position和id相同(以后自己写得Adapter必须用自己的id)
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
case R.id.main_spinner:
adapter_1.clear();
adapter_1.addAll(CITIES[position]);
adapter_2.clear();
adapter_2.addAll(AREAS[spinner.getSelectedItemPosition()][position]);
break;
case R.id.main_spinner_1:
adapter_2.clear();
adapter_2.addAll(AREAS[spinner.getSelectedItemPosition()][position]);
if (adapter_2.isEmpty()) {
spinner_2.setVisibility(View.INVISIBLE);
} else {
spinner_2.setVisibility(View.VISIBLE);
}
break;
case R.id.main_spinner_2:
StringBuilder builder = new StringBuilder();
builder.append(spinner.getSelectedItem()).append(":")
.append(spinner_1.getSelectedItem()).append(":")
.append(spinner_2.getSelectedItem());
Toast.makeText(MainActivity.this, builder.toString(), Toast.LENGTH_SHORT).show();
break;
}
}
//未选中调用
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
效果图: