Android学习(2)

StateListDrawable

针对不同的视图状态加载不同的图片资源来显示的资源选择器。

android:state_pressed 按下
android:state_selected 选中(焦点状态)
android:state_checked 选择框的选择状态
android:state_enable 可用状态

使用方法:

可以在drawable下定义跟标签为selector的xml文件
以选择框的状态为例,文件名为check_button_drawable.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 未选中状态 -->
<item android:drawable="@drawable/button_un_checkedl" android:state_checked="false"/>
<!-- 选中状态 -->
<item android:drawable="@drawable/button_checked" android:state_checked="true"/>
</selector>

布局中直接使用@drawable来加载选择器即可
<CheckBox
    android:id="@+id/ch_1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:button="@drawable/check_button_drawable"
    android:text="选项一" />

<CheckBox
    android:id="@+id/ch_2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="选项二"
    android:button="@null"
    android:drawableLeft="@drawable/check_button_drawable"
    android:checked="true" />

视图的基本状态(以按钮为例)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<!-- 可用未按下 -->
<item android:drawable="@drawable/btn_nomal" android:state_enabled="true" 
android:state_pressed="false"/>

<!-- 可用按下 -->
<item android:drawable="@drawable/btn_press" android:state_enabled="true" 
android:state_pressed="true"/>

<!-- 不可用 -->
<item android:drawable="@drawable/btn_no_enable" android:state_enabled="false"/>
</selector>

使用(设置到背景)
<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="点击有惊喜"
    android:background="@drawable/btn_bg_drawable" />

针对视图的可用状态在xml终态可以使用android:enable属性

android:enabled="false" false表示不可用,默认true表示可用
该属性在Java对应的是
btn.setEnable(true) btn.setEnable(false);
判断是否可用
btn.isEnable();

ColorStateListDrawable

颜色选择器,可以根据不同状态使用不同的颜色值,需要在res下新建一个color文件夹,然后在color文件夹中新建xml文件,根节点为selector,以按钮上的
文本为例,新建一个文件:tx_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 未按下 -->
    <item android:state_enabled="true" android:state_pressed="false" android:color="#000000"/>
    <!-- 按下 -->
    <item android:state_enabled="true" android:state_pressed="true" android:color="@color/white"/>
    <!-- 不可用 -->
    <item android:state_enabled="false" android:color="#666666"/>
    </selector>

在布局中使用

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="点击有惊喜"
    android:textColor="@color/tx_color"
    android:background="@drawable/btn_bg_drawable" />

注意:如果针对视图的背景(也就是需要用图像、图像来显示的地方)使用颜色,则颜色选择的定义属于drawable,定义方式需要在drawable中定义选择器
(如:colorbgdrawable.xml)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- 未按下 -->
        <item android:drawable="@color/red" android:state_pressed="false"/>
        <!-- 按下 -->
        <item android:state_pressed="true">
            <color android:color="#0000ff" />
        </item>
        </selector>

使用

<Button
    android:id="@+id/btn3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/color_bg_drawable"
    android:text="纯颜色的背景" />

shape

可以通过定义shape实现形状的显示,一般放在drawable文件夹中,跟标签为shape

shape属性表示形状类型,默认rectangle矩形,oval椭圆,line线条,ring圆环

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >

    <!-- 渐变填充,跟solid二选一 -->
    <!--
        <gradient
            android:endColor="#EE941A" 起始颜色
            android:centerColor="#ff0000" 中间颜色
            android:startColor="#F6E5AE" 结束颜色
            android:type="sweep" 类型,默认linea线性,radial放射,sweep扫描
            android:angle="90" 角度(只对linear类型有效0从左到右,90从上到下)
            android:centerX="50%" 中心(针对放射以及扫描)x坐标
            android:centerY="50%" /> 中心y坐标
    -->
<!-- 圆角(针对矩形) -->
<corners
    android:bottomRightRadius="20dp"
    android:topLeftRadius="20dp" />
<!-- 纯色填充,跟gradient二选一 -->
<solid android:color="#ff0000" />
<!-- 边框 -->
<stroke             如果是虚线需要添加dashGapdashWidth两个属性
    android:dashGap="5dp" 虚线之间短线间距
    android:dashWidth="15dp" 虚线短线长度
    android:width="2dp"
    android:color="#0000ff" />
<!-- 内容边距 -->
<padding
    android:bottom="3dp"
    android:left="5dp"
    android:right="5dp"
    android:top="3dp" />
</shape>

形状一般用来做背景
如果一个视图中不同状态有不同形状,可以在selector的item中单独定义,也可以直接用@drawable/xxx方式加载

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_pressed="false">
        <shape>
            <corners android:radius="10dp"/>
            <solid android:color="#ff0000"/>
        </shape>
    </item>
    <item android:state_pressed="true">
        <shape>
            <corners android:radius="10dp"/>
            <solid android:color="#ffff00"/>
        </shape>
    </item>
</selector>

Activity之间的跳转

1、定义Activity类(定义的类继承Activity或者其子类,设置布局)

public class LoginActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置界面布局
        setContentView(R.layout.activity_login);
    }
}

2、在manifest.xml中注册Activity

2、在manifest.xml中注册Activity
<activity
android:name="com.xykj.day5.LoginActivity"
android:label="@string/login_activity_label" >
</activity>

3、创建Intent对象,使用startActivity来启动

//创建一个意图
//第一个参数是一个Context对象(Activity\Service\Application)
//第二个参数表示意图要关联的目标,使用的是Class实例
Intent it = new Intent(MainActivity.this,LoginActivity.class);
//启动窗口
startActivity(it);

Activity中的按键监听

可以在Activity中重写onKeyDown或者onKeyUp来监听按键,以监听返回键弹起为例

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
//监听返回键
if(keyCode == KeyEvent.KEYCODE_BACK){
Log.e("m_tag","====onKeyUp====");
//结束当前Activity的方法
finish();
return true;
}
return super.onKeyUp(keyCode, event);
}

滚动视图

辅助其他视图完成滚动,将可见区域之外的内容滚动到区域之内,只能有一个孩子

ScrollView 垂直方向

HorizontalScrollView 水平方向

<ScrollView 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" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            tools:context="com.xykj.day6.MainActivity" >

            ...其他视图...
        </LinearLayout>
</ScrollView>

进度条

进度条ProgressBar,默认是转圈,如果要改为水平的需要添加样式

<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<ProgressBar
    android:id="@+id/progress_bar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="1000"
    android:progress="500"
    android:secondaryProgress="750" />
style="@android:style/Widget.ProgressBar.Horizontal"    表示设置进度条为水平长条
android:max="1000"                                      最大值,默认100
android:progress="500"                                  实际进度,第一进度

java中设置进度

    java中设置进度
    progress = (ProgressBar) findViewById(R.id.progress_bar);
    //设置最大值
    progress.setMax(100);
    //设置实进度
    progress.setProgress(10);
    //设置第二进度
    progress.setSecondaryProgress(30);

拖动条,SeekBar,继承自ProgressBar,有一个拖块可以让用户来改变进度值

<SeekBar
    android:id="@+id/seek"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
java:
    mSeek = (SeekBar) findViewById(R.id.seek);
    //监听进度变化
    mSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
        //停止拖动
        @Override
        public void onStopTrackingTouch(SeekBar bar) {
        Log.e("m_tag","onStopTrackingTouch");
        }

        //开始拖动
        @Override
        public void onStartTrackingTouch(SeekBar bar) {
        Log.e("m_tag","onStartTrackingTouch");
        }

        //进度变化的时候触发
        //第三个参数表示是否是用户拖动拖块导致进度变化的,是则为true
        @Override
        public void onProgressChanged(SeekBar bar, int progress, boolean isFromUser) {
        Log.e("m_tag","progress:"+progress+" isFromUser:"+isFromUser);
    }
});

评分组件,可以使用星星来表示分值的组件,半颗星默认0.5分一颗1分

<RatingBar
    android:id="@+id/rating"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:rating="1.5"
    android:numStars="5"
/>
    如果加上android:isIndicator="true"表示为指示器,只可以看不可以拖(只能程序改变分值,用户不能改变分值)
    java中监听
    mRating.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {

        @Override
        public void onRatingChanged(RatingBar bar, float rating, boolean isFromUser) {
        Log.e("m_tag","rating:"+rating);
    }
});

自定义进度条

在drawable文件中新建xml文件,根节点为layer-list,然后分别设置背景、第二进度、第一进度的图片资源

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 背景层 -->
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/bg"/>
    <!-- 第二进度 -->
    <item
        android:id="@android:id/secondaryProgress"
        android:drawable="@drawable/s_pro"/>
    <!-- 第一进度 -->
    <item
        android:id="@android:id/progress"
        android:drawable="@drawable/pro"/>
</layer-list>

使用,可以在进度条上设置android:progressDrawable属性

<ProgressBar
    android:id="@+id/progress_bar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="1000"
    android:progress="500"
    android:progressDrawable="@drawable/progress_drawable" />
<SeekBar
    android:id="@+id/seek"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:progressDrawable="@drawable/progress_drawable" />

关于拖动条的拖块,可以定义一个selector文件,处理未按下以及按下的图片,然后使用android:thumb属性添加即可

trhumb_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/btn_nomal" android:state_pressed="false"/>
    <item android:drawable="@drawable/btn_pressn" android:state_pressed="true"/>

</selector>

设置拖块

<SeekBar
android:id="@+id/seek"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/progress_drawable"
android:thumb="@drawable/thumb_drawable"/>

对于评分组件,可以使用第二进度来表示半颗星

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<item
    android:id="@android:id/background"
    android:drawable="@drawable/star_bg"/>
<!-- 评分控件半颗星用第二进度表示 -->

<item
    android:id="@android:id/secondaryProgress"
    android:drawable="@drawable/star_harf"/>

<item
    android:id="@android:id/progress"
    android:drawable="@drawable/star"/>
</layer-list>

使用
<RatingBar
    android:id="@+id/rating"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:rating="1.5"
    android:numStars="5"
    android:progressDrawable="@drawable/rating_drawale" />

子线程

Android中只允许在主线程中更新UI,子线程中如果要更新UI,则需要将信息发布给主线程(跟主线程通讯),让主线程来更新
1、定义线程,在线程中处理耗时业务,并且需要更新UI时发消息给主线程

private Thread t;

private void autoUpdate() {
    //如果已经有线程在更新进度,则不再更新
    if (t != null && t.isAlive()) {
        return;
    }
    t = new Thread() {
        @Override
        public void run() {
        try {
            while (progress.getProgress() < progress.getMax()) {
                    Thread.sleep(500);
                    // 获取当前进度
                    int current = progress.getProgress();
                    current += 5;
                    // 将新的进度值显示出来
                    Message msg = new Message();
                    msg.what = 1; // 消息编号
                    msg.obj = current; // 消息携带的内容(Object)
                    mHandler.sendMessage(msg);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    // 启动线程
    t.start();
}

注意:消息发送时可以使用以下方法简化消息创建过程

mHandler.obtainMessage(1, current).sendToTarget();

2、主线程中可以定义Handler对象来接收消息,并且更新UI

// 接收消息的对象
private Handler mHandler = new Handler() {
    // 接收其他地方发来的消息
        public void handleMessage(android.os.Message msg) {
            // 主线程中
            if(msg.what==1){
                int pro = (Integer)msg.obj;
                progress.setProgress(pro);
        }
    }
};

猜你喜欢

转载自blog.csdn.net/lonely0512/article/details/80659841