Android开发学习-中级控件

Drawable

Android把所有能够显示的图形都抽象为Drawable类(可绘制的)。

这里的图形不止是图片,还包括色块、画板、背景等。
包含图片在内的图形文件放在res目录的各个drawable目录下,其中drawable目录一般保存描述性的XML文件,而图片文件一般放在具体分辨率的drawable目录下。例如:

同尺寸的手机有可能分辨率不同,手机分辨率就高不就低,因为分辨率低了屏幕会有模糊的感觉)。
drawable-ldpi里面存放低分辨率的图片 (如240x320),现在基本没有这样的智能手机了
drawable-mdpi里面存放中等分辨率的图片 (如320x480) ,这样的智能手机已经很少了
drawable-hdp里面存放高分辨率的图片(如480X800),一般对应4英寸~4.5英寸的手机(但不绝对,
drawable-xhdpi里面存放加高分辨率的图片 (如720x1280) ,一般对应5英寸~5.5英寸的手机。drawable-xxhdpi里面存放超高分辨率的图片 (如1080x1920),一般对应6英寸~6.5英寸的手机
drawable-xxxhdpi里面存放超超高分辨率的图片(如1440x2560) ,一般对应7英寸以上的平板电脑
基本上,分辨率每加大一级,宽度和高度就要增加二分之一或三分之一像素。

如果各目录存在同名图片,Android就会根据手机的分辨率分别适配对应文件夹里的图片。

在开发App时,为了兼容不同的手机屏幕,在各目录存放不同分辨率的图片,才能达到最合适的显示效果。例如,在drawable-hdpi放了一张背景图片bg,png (分辨率为480x800),其他目录没放,使用分辨率为480X800的手机查看该App界面没有问题,但是使用分辨率为720x1280的手机查看该App会发现背景图片有点模糊,原因是Android为了让bg,png适配高分辨率的屏幕,强行把bg.png拉伸到了720x1280,拉伸的后果是图片变模糊了。
在XML布局文件中引用图形文件可使用“@drawable/不含扩展名的文件名称”这种形式,如各视图的background属性、ImageView和lmageButton的src属性、TextView和Button四个方向的drawable***系列属性都可以引用图形文件。

形状shape图形

shape图形又称形状图形,它用来描述常见的几何形状,包括矩形、圆角矩形、圆形、椭圆等。用好形状图形可以让App页面不再呆板还可以节省美工不少工作量。
形状图形的定义文件放在drawable目录下,它是以shape标签为根节点的XML描述文件。根节点下定义了6个节点,分别是: size(尺寸)、stroke(描边)、corners (圆角)、solid (填充)、padding (间隔)、gradient(渐变),各节点的属性值主要是长宽、半径、角度以及颜色等。下面是形状图形各个节点及其属性的简要说明。
1. shape (形状)
shape是形状图形文件的根节点,它描述了当前是哪种几何图形。下面是shape节点的常用属性说明。

形状类型说明
rectangle矩形。默认值
oval椭圆。此时corners节点会失效
line直线。此时必须设置stroke节点,不然会报错
ring圆环

代码:

shape_rect_gold.xml
shape_rect_voal.xml 

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

<!--    指定形状内部填充颜色-->
    <solid android:color="#ffdd66"></solid>
<!--    指定形状轮廓与颜色-->
<stroke android:width="1dp" android:color="#aaaaaa"/>
<!--    指定四个圆角的半径-->

    <corners android:radius="10dp"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">


<!--    指定形状内部填充颜色-->
    <solid android:color="#ff66aa"></solid>
<!--    指定形状轮廓与颜色-->
<stroke android:width="1dp" android:color="#aaaaaa"/>
<!--    指定四个圆角的半径-->

</shape>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.pshdhx.middleComponent.ShapeActivity">

    <View
        android:id="@+id/view_content"
        android:layout_width="match_parent"
        android:layout_height="300dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_rect"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_weight="1"
            android:text="矩形"
            />
        <Button
            android:id="@+id/btn_oval"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_weight="1"
            android:text="椭圆"
            />
    </LinearLayout>

</LinearLayout>
public class ShapeActivity extends AppCompatActivity implements View.OnClickListener {

    View view;

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

        view = findViewById(R.id.view_content);
        view.setBackgroundResource(R.drawable.shape_rect_gold);
        findViewById(R.id.btn_rect).setOnClickListener(this);
        findViewById(R.id.btn_oval).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_rect:
                view.setBackgroundResource(R.drawable.shape_rect_gold);
                break;
            case R.id.btn_oval:
                view.setBackgroundResource(R.drawable.shape_rect_voal);
                break;
        }
    }
}

效果:

九宫格图片-.9图片

将某张图片设置成视图背景时,如果图片尺寸太小,则系统会自动拉伸图片将之填满背景。

可是一旦图片拉的过大,其画面容易变得模糊。

九宫格图片*.9.png可以控制边角处,不会进行拉伸。

上边缘线和左边缘线控制水平和竖直的拉伸效果,将其设置,可以不拉伸边角处。

下边缘线和右边缘线控制文字在显示区域内的效果。

图形状态列表

状态类型的属性名称说明适用的控件
state_pressed是否按下按钮Button
state_checked是否勾选复选框CheckBox、单选按钮RadioButton
state_focused是否获取焦点文本编辑框EditText
state_selected是否选中各控件通用

btn_selector.xml 

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

    <item android:state_pressed="true" android:drawable="@drawable/shape_rect_gold"/>
    <item  android:drawable="@drawable/shape_rect_voal"/>
</selector>
android:background="@drawable/btn_selector"

复选框-checkbox

CompoundButton再xml中,主要使用以下两个属性

        checked:指定勾选状态true/false

        button:指定左侧勾选图标的图形资源,如果不指定,则系统默认。

CompoundButton在Java中主要使用下列4种方法

        setChecked

        setButtonDrawable:设置左侧勾选图标的图形资源

        setOnCheckedChangeListener:监听器

        isChecked

开关按钮-switch

textOn:设置右侧开启时的文本

textOff:设置左侧关闭时的文本

track:设置开关轨道的背景

thumb:设置开关表示的图标

单选按钮组

RadioGroup

RadioButton

文本输入框-EditText

监听文本编辑器

addTextChangedListener

beforeTextChanged:在文本改变之前触发

onTextChanged:在文本改变过程中触发

afterTextChanged:在文本改变之后触发

edit_phone.addTextChangedListener(new HideTextWatcher(edit_phone,11));

private class HideTextWatcher implements TextWatcher{
    private EditText mView;
    private int maxLength;
    public HideTextWatcher(EditText v,int maxLength){
        this.mView = v;
        this.maxLength = maxLength;
    }
}

对话框

提醒对话框-AlertDialog

就是卸载时,带着确认或者是取消的对话框

<Button
        android:id="@+id/btn_alert_dialog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="alertDialog"
        android:text="点击弹出对话框"/>
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
public void alertDialog(View view) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        TextView tv_result = findViewById(R.id.tv_result);
        builder.setTitle("尊敬的用户");
        builder.setMessage("你真的要卸载吗?");
        builder.setPositiveButton("残忍卸载",(dialog,witch)->{
            tv_result.setText("我已残忍卸载");
        });

        builder.setNegativeButton("我再想一下",(dialog,witch)->{
            tv_result.setText("我再想一下吧!");
        });
        AlertDialog alertDialog = builder.create();
        alertDialog.show();
    }

setIcon:设置对话框的标题图标

setNeutralButton:设置中性按钮的信息,包括按钮文本和点击的监听器。

日期对话框-DatePickerDialog

<Button
        android:id="@+id/selectDateDialog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="selectDateDialog"
        android:text="请选择日期"/>


    <DatePicker
        android:id="@+id/date_picker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:datePickerMode="spinner"
        android:calendarViewShown="false"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="确定"
        android:onClick="selectDateClick"
        android:id="@+id/btn_ok"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_date"/>
public class DatePickerDialogActivity extends AppCompatActivity implements DatePickerDialog.OnDateSetListener {

    TextView tv_date;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_date_picker_dialog);
        tv_date = findViewById(R.id.tv_date);
    }


    public void selectDateClick(View view) {

        DatePicker date_picker = findViewById(R.id.date_picker);
        String desc = String.format("您选择的日期是%s",date_picker.getYear()+"-"+(date_picker.getMonth()+1)+"-"+date_picker.getDayOfMonth());
        tv_date.setText(desc);

    }

    public void selectDateDialog(View view) {
        DatePickerDialog dialog = new DatePickerDialog(this,this,2090,5,20);
        dialog.show();
    }

    @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        String desc = String.format("您选择的日期是%s",year+"-"+(month+1)+"-"+dayOfMonth);
        Toast.makeText(this,desc,Toast.LENGTH_LONG).show();
        tv_date.setText(desc);
    }
}

结果:

时间对话框-TimePickerDialog

<Button
        android:id="@+id/selectTimeDialog"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="selectTimeDialog"
        android:text="请选择时间"/>


    <TimePicker
        android:id="@+id/time_picker"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:timePickerMode="spinner"
        />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="确定"
        android:onClick="selectTimeClick"
        android:id="@+id/btn_ok"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_time"/>
public class TimePickerActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {

    TextView tv_time;
    TimePicker time_picker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_time_picker);
        tv_time = findViewById(R.id.tv_time);
        time_picker = findViewById(R.id.time_picker);
    }

    public void selectTimeDialog(View view) {
        TimePickerDialog dialog = new TimePickerDialog(this,android.R.style.Theme_Holo_Light_Dialog_NoActionBar, this, Calendar.getInstance().get(Calendar.HOUR_OF_DAY),Calendar.getInstance().get(Calendar.MINUTE),true);
        dialog.show();

    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void selectTimeClick(View view) {
        String desc = String.format("您选择的时间是%s",time_picker.getHour()+":"+time_picker.getMinute());
        tv_time.setText(desc);
    }

    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        String desc = String.format("您选择的时间是%s",hourOfDay+":"+minute);
        tv_time.setText(desc);
    }
}

效果 

 

登录Demo 

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.pshdhx.middleComponent.LoginMainActivity">


    <RadioGroup
        android:id="@+id/rg_login"
        android:layout_width="match_parent"
        android:layout_height="@dimen/item_layout_height"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/rb_password"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:checked="true"
            android:text="@string/login_by_password"
            android:textSize="@dimen/common_font_size" />

        <RadioButton
            android:id="@+id/rb_verifycode"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="@string/login_by_verifycode"
            android:textSize="@dimen/common_font_size" />

    </RadioGroup>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/item_layout_height"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="@string/phone_number"
            android:textColor="@color/black"
            android:textSize="@dimen/common_font_size" />
        
        <EditText
            android:id="@+id/et_phone"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:hint="@string/input_phone_number"
            android:inputType="number"
            android:maxLength="11"
            android:textSize="@dimen/common_font_size"
            />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/item_layout_height"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tv_password"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="@string/login_password"
            android:textColor="@color/black"
            android:textSize="@dimen/common_font_size" />

        <EditText
            android:id="@+id/et_password"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:hint="@string/input_password"
            android:inputType="numberPassword"
            android:maxLength="6"
            android:textSize="@dimen/common_font_size"
            />
        <Button
            android:id="@+id/btn_forgetPassword"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:textSize="@dimen/common_font_size"
            android:text="@string/forget_password"
            android:textColor="@color/black"
            android:background="@color/design_default_color_primary_dark"/>

    </LinearLayout>

    <CheckBox
        android:id="@+id/ck_remember"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/remember_password"
        android:textColor="@color/black"
        android:textSize="@dimen/common_font_size"/>

    <Button
        android:id="@+id/btn_login"
        android:layout_width="match_parent"
        android:layout_height="@dimen/item_layout_height"
        android:text="@string/login"
        android:textColor="@color/black"
        android:textSize="@dimen/common_font_size"/>

</LinearLayout>

 代码文件:

public class LoginMainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, View.OnClickListener {
    RadioGroup rg_login;
    TextView tv_password;
    EditText et_password;
    EditText et_phone;
    Button btn_forgetPassword;
    Button btn_login;
    CheckBox ck_remember;
    RadioButton rb_password;
    RadioButton rb_verifycode;
    private String mVerifyCode = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login_main);
        rg_login = findViewById(R.id.rg_login);
        btn_login = findViewById(R.id.btn_login);
        rb_password = findViewById(R.id.rb_password);
        rb_verifycode = findViewById(R.id.rb_verifycode);
        tv_password = findViewById(R.id.tv_password);
        et_password = findViewById(R.id.et_password);
        et_phone = findViewById(R.id.et_phone);
        et_phone.addTextChangedListener(new HideTextWatcher(et_phone, 11));
        et_password.addTextChangedListener(new HideTextWatcher(et_password, 6));
        btn_forgetPassword = findViewById(R.id.btn_forgetPassword);
        ck_remember = findViewById(R.id.ck_remember);
        rg_login.setOnCheckedChangeListener(this);
        btn_login.setOnClickListener(this);

        btn_forgetPassword.setOnClickListener(this);
    }

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.rb_password:
                tv_password.setText(getString(R.string.login_password));
                et_password.setHint(getString(R.string.input_password));
                btn_forgetPassword.setText(getString(R.string.forget_password));
                ck_remember.setVisibility(View.VISIBLE);
                break;
            case R.id.rb_verifycode:
                tv_password.setText(getString(R.string.verifycode));
                et_password.setHint(getString(R.string.input_verifycode));
                btn_forgetPassword.setText(getString(R.string.get_verifycode));
                ck_remember.setVisibility(View.GONE);
                break;
        }
    }

    @Override
    public void onClick(View v) {
        String phone = et_phone.getText().toString();
        String password = et_password.getText().toString();
        switch (v.getId()) {
            case R.id.btn_forgetPassword:
                if (phone.length() < 11) {
                    Toast.makeText(this, "请输入正确的手机号码", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (rb_password.isChecked()) {
                    Intent intent = new Intent(this, LoginForgetActivity.class);
                    intent.putExtra("phone", phone);
                    startActivityForResult(intent, 8888);
                } else if (rb_verifycode.isChecked()) {
                    mVerifyCode = String.format("%6d", new Random().nextInt(999999));
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("请记住验证码");
                    builder.setMessage("手机号" + phone + "本次验证码是" + mVerifyCode + ",请输入验证码");
                    builder.setPositiveButton("好的", null);
                    AlertDialog alertDialog = builder.create();
                    alertDialog.show();
                }
                break;
            case R.id.btn_login:
                if(rb_password.isChecked()){
                    if(!password.equals("111111")){
                        Toast.makeText(this,"请输入正确的密码",Toast.LENGTH_SHORT).show();
                        return ;
                    }
                    loginSuccess();
                }else if(rb_verifycode.isChecked()){
                    if(!mVerifyCode.equals(et_password.getText().toString())){
                        Toast.makeText(this,"请输入正确的验证码",Toast.LENGTH_SHORT).show();
                        return ;
                    }
                    loginSuccess();
                }
                break;

        }
    }

    private void loginSuccess() {
        Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

    private class HideTextWatcher implements TextWatcher {

        private EditText mView;
        private int maxLength;

        public HideTextWatcher(EditText et_phone, int i) {
            this.mView = et_phone;
            this.maxLength = i;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (s.toString().length() == maxLength) {
                ViewUtils.hideOneInputMethod(LoginMainActivity.this, mView);
            }
        }
    }
}

public class ViewUtils {
    public static void hideOneInputMethod(Context context, EditText mView) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mView.getWindowToken(), 0);
    }
}

 效果图:

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值