文章目录

  • 基本UI组件
    • 文本框组件
      • TextView组件
      • EditText编辑框组件
    • 按钮组件
      • 普通按钮
      • 图片按钮ImageButton
      • 单选按钮RadioButton
      • 复选按钮CheckBox
      • 日期选择器
      • 时间选择器
      • 计时器
  • 高级UI组件
    • 进度条
    • 拖动条
    • 星星评分条
    • 图像视图
    • 图像切换器
    • 网格视图进阶
    • 下拉列表框
    • 列表视图
    • 滚动视图
    • 选项卡

基本UI组件

  • 文本类组件
  • 按钮类组件
  • 日期时间类组件

文本框组件

主要用于显示文本信息

TextView组件

TextView的常用属性

  • layout_width
  • layout_height
  • text
  • textSize
  • textColor
  • singleLine 单行超出部分省略号
  • 画图 如下EditText

EditText编辑框组件

  • layout_width
  • layout_height
  • hint 相当于input框的placeholder
  • inputType 定义输入内容的类型 例如 textPassword
  • drawableLeft 在左侧绘制图像 属性值为图片资源 Start Bottom End Right Top
  • drawablePadding 绘制的图像和文字的间距
  • lines 控制最大输入行数,超过行数后拖动查看
  • gravity 内容显示位置

按钮组件

属性类似与TextView

普通按钮

两种方式实现按钮触发事件

  1. 通过获取id的方式
package com.liyanfeng.yuansu;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements View.OnClickListener {// 定义私有属性  button1private Button button1;private Button button2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}// 帝国一initView方法获取按钮对象private void initView() {// 获取方法获取的为VIew需要显示转换button1 = (Button) findViewById(R.id.button1);button1.setOnClickListener(this);button2 = (Button) findViewById(R.id.button2);button2.setOnClickListener(this);}// 重写同意的onClick发给发@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button1:Toast.makeText(MainActivity.this, "单击事件--按钮1", Toast.LENGTH_SHORT).show();break;case R.id.button2:Toast.makeText(MainActivity.this, "单击事件--按钮2", Toast.LENGTH_SHORT).show();break;}}
}
  1. 通过属性绑定方法的方式

按钮3

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"tools:context=".MainActivity"><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/button_1" /><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/button1"android:text="@string/button_2" /><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/button1"android:layout_toEndOf="@id/button2"android:layout_toRightOf="@id/button2"android:text="@string/button_3"android:onClick="myClick"android:shadowRadius="5"/>
</RelativeLayout>
package com.liyanfeng.yuansu;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements View.OnClickListener {// 定义私有属性  button1private Button button1;private Button button2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}// 帝国一initView方法获取按钮对象private void initView() {// 获取方法获取的为VIew需要显示转换button1 = (Button) findViewById(R.id.button1);button1.setOnClickListener(this);button2 = (Button) findViewById(R.id.button2);button2.setOnClickListener(this);}// 重写同意的onClick发给发@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button1:Toast.makeText(MainActivity.this, "单击事件--按钮1", Toast.LENGTH_SHORT).show();break;case R.id.button2:Toast.makeText(MainActivity.this, "单击事件--按钮2", Toast.LENGTH_SHORT).show();break;}}// 属性绑定的方式public void myClick(View v) {Toast.makeText(MainActivity.this, "属性绑定事件", Toast.LENGTH_SHORT).show();}
}

图片按钮ImageButton

和普通按钮功能一致,均可以触发onClick事件,普通按钮通过text指定文字,但是图片按钮没有text属性,src指定图片资源,设置图片资源后出现灰色背景要通过background属性#0000全透明实现

// 设置全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)

单选按钮RadioButton

  • text
  • checked 被选中状态

单选按钮组 RadioGroup

同组的单选按钮只能有一个被选中

获取单选按钮组中被选中的值

    <RadioGroupandroid:id="@+id/rgroup1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/line1"><RadioButtonandroid:id="@+id/g1s1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="单选A" /><RadioButtonandroid:id="@+id/g1s2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="单选B" /><RadioButtonandroid:id="@+id/g1s3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="单选C" /></RadioGroup>
package com.liyanfeng.yuansu;import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements View.OnClickListener, RadioGroup.OnCheckedChangeListener {// 定义私有属性  button1private RadioButton g1s1;private RadioButton g1s2;private RadioButton g1s3;private RadioGroup rgroup1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 全屏显示隐藏状态栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);initView();}// 帝国一initView方法获取按钮对象private void initView() {// 获取方法获取的为VIew需要显示转换g1s1 = (RadioButton) findViewById(R.id.g1s1);g1s2 = (RadioButton) findViewById(R.id.g1s2);g1s3 = (RadioButton) findViewById(R.id.g1s3);rgroup1 = (RadioGroup) findViewById(R.id.rgroup1);// 添加change事件rgroup1.setOnCheckedChangeListener(this);}@Override// 重写change事件public void onCheckedChanged(RadioGroup group, int checkedId) {switch (group.getId()) {case R.id.rgroup1:RadioButton current_checked = (RadioButton) findViewById(checkedId);String gtext = (String) current_checked.getText();Toast.makeText(MainActivity.this, "结果:" + gtext, Toast.LENGTH_SHORT).show();break;}}
}

选择题

<?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"tools:context=".MainActivity"android:orientation="vertical"android:padding="5dp"><RadioGroupandroid:id="@+id/rgroup1"android:layout_width="wrap_content"android:layout_height="wrap_content"><RadioButtonandroid:id="@+id/g1s1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="单选A" /><RadioButtonandroid:id="@+id/g1s2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="单选B" /><RadioButtonandroid:id="@+id/g1s3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="单选C" /></RadioGroup><Buttonandroid:id="@+id/submit_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="提交" /><TextViewandroid:id="@+id/line2"android:layout_width="match_parent"android:layout_height="2dp"android:background="#CCC" />
</LinearLayout>

package com.liyanfeng.yuansu;import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements View.OnClickListener, RadioGroup.OnCheckedChangeListener {// 定义私有属性  button1private RadioGroup rgroup1;private Button submitBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 全屏显示隐藏状态栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);initView();}// 帝国一initView方法获取按钮对象private void initView() {// 获取方法获取的为VIew需要显示转换rgroup1 = (RadioGroup) findViewById(R.id.rgroup1);submitBtn = findViewById(R.id.submit_btn);submitBtn.setOnClickListener(this);}// 重写同意的onClick发给发@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.submit_btn:// 遍历单选按钮组for (int i = 0; i < rgroup1.getChildCount(); i++) {RadioButton ele = (RadioButton) rgroup1.getChildAt(i);if (ele.isChecked()) {Toast.makeText(MainActivity.this,"被选中的是:" + ele.getText(),Toast.LENGTH_SHORT).show();break;}}break;}}
}

复选按钮CheckBox

属性类似于单选按钮

复选hobby

<?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"android:padding="5dp"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="复选按钮"android:textColor="#000"android:textSize="20sp" /><TextViewandroid:layout_width="match_parent"android:layout_height="2dp"android:layout_marginTop="5dp"android:background="#CCC"android:padding="1dp" /><CheckBoxandroid:id="@+id/hobby1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="美术" /><CheckBoxandroid:id="@+id/hobby2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="体育" /><CheckBoxandroid:id="@+id/hobby3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="音乐" /><Buttonandroid:id="@+id/submit_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="提交" />
</LinearLayout>
package com.liyanfeng.buju2;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import org.json.JSONArray;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private CheckBox hobby1;private CheckBox hobby2;private CheckBox hobby3;private Button submitBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {hobby1 = findViewById(R.id.hobby1);hobby2 = findViewById(R.id.hobby2);hobby3 = findViewById(R.id.hobby3);submitBtn = findViewById(R.id.submit_btn);submitBtn.setOnClickListener(this);}@Overridepublic void onClick(View v) {List<String> res = new ArrayList<>();switch (v.getId()) {case R.id.submit_btn:if (hobby1.isChecked()) {res.add(hobby1.getText().toString());}if (hobby2.isChecked()) {res.add(hobby2.getText().toString());}if (hobby3.isChecked()) {res.add(hobby3.getText().toString());}Toast.makeText(this, new JSONArray(res).toString(), Toast.LENGTH_SHORT).show();break;}}
}

日期选择器

DatePicker

AppCompatActivity 是带有标题栏的Activity 而Activity 是不带有标题栏的


<?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"android:padding="5dp"tools:context=".MainActivity"><DatePickerandroid:id="@+id/dp1"android:layout_gravity="center_horizontal"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>
package com.liyanfeng.xuanzeqi;import android.app.Activity;
import android.os.Bundle;
import android.widget.DatePicker;
import android.widget.Toast;import java.util.Calendar;public class MainActivity extends Activity implements DatePicker.OnDateChangedListener {private DatePicker dp1;private int year, month, day;private Calendar calendar; // 日历对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {calendar = Calendar.getInstance();// 获取当前日期年月日year = calendar.get(Calendar.YEAR);month = calendar.get(Calendar.MONTH);day = calendar.get(Calendar.DAY_OF_MONTH);dp1 = (DatePicker) findViewById(R.id.dp1);// 初始化DatePicker 并添加change事件dp1.init(year, month, day, this);}@Overridepublic void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {switch (view.getId()) {case R.id.dp1:show(year, monthOfYear, dayOfMonth);break;}}private void show(int year, int month, int day) {// month+1才能显示中国的月份String str = year + "-" + (month + 1) + "-" + day;Toast.makeText(this, str, Toast.LENGTH_SHORT).show();}
}

时间选择器

TimePicker

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:padding="5dp"tools:context=".MainActivity"><TimePickerandroid:id="@+id/tp1"android:layout_width="wrap_content"android:layout_height="wrap_content"/></RelativeLayout>
package com.liyanfeng.xuanzeshijian;import android.app.Activity;
import android.os.Bundle;
import android.widget.TimePicker;
import android.widget.Toast;public class MainActivity extends Activity implements TimePicker.OnTimeChangedListener {private TimePicker tp1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {tp1 = (TimePicker) findViewById(R.id.tp1);tp1.setIs24HourView(true);tp1.setOnTimeChangedListener(this);}@Overridepublic void onTimeChanged(TimePicker view, int hourOfDay, int minute) {switch (view.getId()) {case R.id.tp1:show(hourOfDay, minute);break;}}private void show(int h, int m) {String res = h + "时" + m + "分";Toast.makeText(this, res, Toast.LENGTH_SHORT).show();}
}

计时器

Chronometer

常用方法

  • setBase() 计时器的起始时间
  • setFormat() 显示的时间格式
  • start() 开指定始计时器
  • stop() 停止指定计时器
  • setOnChronometerTickListener() 计时器的改变监听事件

1h内的倒计时功能

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"tools:context=".MainActivity"><Chronometerandroid:id="@+id/jsq1"android:layout_width="wrap_content"android:layout_height="wrap_content" />
</FrameLayout>
package com.liyanfeng.jishiqi;import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Chronometer;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private Chronometer jsq1;private long allTime = 90;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeJsq();}private void initView() {getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);jsq1 = (Chronometer) findViewById(R.id.jsq1);}private void makeJsq() {// 起始时间  系统时间jsq1.setBase(SystemClock.elapsedRealtime());jsq1.start();jsq1.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {@Overridepublic void onChronometerTick(Chronometer chronometer) {long throughTime = (SystemClock.elapsedRealtime() - chronometer.getBase()) / 1000;String remainingTime = String.valueOf(allTime - throughTime);if (remainingTime.length() < 2) {remainingTime = "00:0" + remainingTime;} else {int h = Integer.parseInt(remainingTime) / 60;int yh = Integer.parseInt(remainingTime) % 60;if (String.valueOf(h).length() < 2) {remainingTime = "0" + h + ":";if (String.valueOf(yh).length() < 2) {remainingTime += "0" + yh;} else {remainingTime += String.valueOf(yh);}} else {remainingTime = h + ":";if (String.valueOf(yh).length() < 2) {remainingTime += "0" + yh;} else {remainingTime += String.valueOf(yh);}}}Log.i("剩余时间:", remainingTime);jsq1.setText(remainingTime);if (throughTime >= allTime) {jsq1.stop();}}});}
}

高级UI组件

  • 进度条类
  • 图像类
  • 列表类
  • 通用类

进度条

  • 水平进度条
  • 圆形进度条/loading

默认为圆形进度条

  • style

    • 通过主题属性设置:?andorid:attr/xxxx/xxxxStyleXxxx
    • 通过内置属性设置:@andorid:xxxx
  • max 设置最大值
  • progress 当前值

实现进度条的改变

创建个线程->判断是否完成->更新进度

setProgress() 更新进度

setVisibility() 完成后设置进度条不显示

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"tools:context=".MainActivity"><ProgressBarandroid:id="@+id/pb1"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:max="100" /></RelativeLayout>
package com.liyanfeng.jindutiao;import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private ProgressBar pb1;private int currentProgress = 0;private Handler progressBarHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeProgressBar();}private void initView() {// 获取view对象pb1 = (ProgressBar) findViewById(R.id.pb1);}@SuppressLint("HandlerLeak")private void makeProgressBar() {progressBarHandler = new Handler() {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);if (msg.what == 0x111) {// 更新进度pb1.setProgress(currentProgress);} else {Toast.makeText(MainActivity.this, "完成", Toast.LENGTH_SHORT).show();pb1.setVisibility(View.GONE);}}};// 创建线程去查询是否完成new Thread(new Runnable() {@Overridepublic void run() {while (true) {currentProgress = doWork();// 创建消息对象更新进度条的进度Message msg = new Message();if (currentProgress < 100) {// 设置消息代码 未完成 格式一般0x???msg.what = 0x111;progressBarHandler.sendMessage(msg);} else {// 设置消息代码 完成msg.what = 0x110;progressBarHandler.sendMessage(msg);break; // 退出线程}}}}).start();}private int doWork() {currentProgress += Math.random() * 10;try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}return currentProgress;}
}

拖动条

SeekBar

  • max
  • progress
  • thumb 可以是图片资源 拖动按钮样式

托动态改变图片的透明度

<?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:background="#CCC"android:gravity="center_horizontal"android:orientation="vertical"tools:context=".MainActivity"><ImageViewandroid:id="@+id/img1"android:layout_width="match_parent"android:layout_height="300dp"android:layout_margin="10dp"android:src="@drawable/res" /><SeekBarandroid:id="@+id/skb1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:max="255"android:progress="255"/></LinearLayout>
package com.liyanfeng.tuodongtiao;import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {// 拖动条  改变图片的透明度private SeekBar skb1;private ImageView img1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);initView();}private void initView() {skb1 = (SeekBar) findViewById(R.id.skb1);skb1.setOnSeekBarChangeListener(this);img1 = (ImageView) findViewById(R.id.img1);}@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {img1.setImageAlpha(progress);Log.i("onProgressChanged", "进度改变:" + progress);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {Log.i("onStartTrackingTouch", "开始触摸");}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {Log.i("onStopTrackingTouch", "结束触摸");}}

星星评分条

RatingBar

默认星星数量5颗

  • android:numStars 星星数量
  • android:rating 默认点亮数量
  • android:stepSize=“1” 不设置这个属性星星可以半颗点亮
  • android:isIndicator true 关闭触摸
<?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=".MainActivity"><RatingBarandroid:id="@+id/startBar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:numStars="5"android:rating="5"android:stepSize="1" /><Buttonandroid:id="@+id/getValueBtn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="获取分值" /></LinearLayout>
package com.liyanfeng.xingxingpingfentiao;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.RatingBar;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private RatingBar startBar;private Button getValueBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeRatingBar();}private void initView() {startBar = (RatingBar) findViewById(R.id.startBar);getValueBtn = (Button) findViewById(R.id.getValueBtn);getValueBtn.setOnClickListener(this);}private void makeRatingBar() {// 选中几颗星String rating = String.valueOf(startBar.getRating());String stepSize = String.valueOf(startBar.getStepSize());String progress = String.valueOf(startBar.getProgress());Log.i("选中:", rating);Log.i("至少选中:", stepSize);Log.i("当前进度:", progress);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.getValueBtn:Float res = startBar.getRating();Log.i("得到", String.valueOf(res));break;}}
}

图像视图

ImageView

默认图片是等比缩放的,改变高度或者宽度后不变形

  • src 指定图片资源
  • scaleType 更改图片的缩放属性
  • adjustViewBounds 是否调整边界保证图片的纵横比 配合mmaxWidth/Height使用
  • maxWidth 最大宽度
  • maxHeight 最大高度
  • tint 着色属性,添加蒙版,ARGB颜色

在AndroidManifest.xml 的activity中添加android:screenOrientation="landscape"属性,只允许横屏展示

图像切换器

ImageSwitcher

简单一次切换

<?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:gravity="center"tools:context=".MainActivity"><ImageSwitcherandroid:id="@+id/imgSr"android:layout_width="match_parent"android:layout_height="match_parent" />
</LinearLayout>
package com.liyanfeng.imageswith;import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ViewSwitcher;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private ImageSwitcher imgSr;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeImageSwither();}private void initView() {imgSr = (ImageSwitcher) findViewById(R.id.imgSr);}private void makeImageSwither() {// 设置进场动画imgSr.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));// 离开动画imgSr.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 250);imgSr.setLayoutParams(params);// 设置动画工厂imgSr.setFactory(new ViewSwitcher.ViewFactory() {@Overridepublic View makeView() {ImageView iv = new ImageView(MainActivity.this);iv.setImageResource(R.drawable.img1);return iv;}});// 设置点击切换时间imgSr.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.imgSr:ImageSwitcher i = (ImageSwitcher) v;i.setImageResource(R.drawable.img2);break;}}
}

滑动相册

<?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:gravity="center"android:padding="5dp"tools:context=".MainActivity"><ImageSwitcherandroid:id="@+id/imgSwitcher"android:layout_height="250dp"android:layout_width="250dp" /></LinearLayout>
package com.liyanfeng.huadongxiangpian;import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements View.OnTouchListener {private ImageSwitcher imgSwitcher;private int[] imgArray = new int[]{R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4,};private int currentImg;private float startTouchX;private float endTouchX;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);initView();makeImageSwither();}private void initView() {imgSwitcher = (ImageSwitcher) findViewById(R.id.imgSwitcher);}@SuppressLint("ClickableViewAccessibility")private void makeImageSwither() {// 设置触摸事件监听器imgSwitcher.setOnTouchListener(this);imgSwitcher.setFactory(new ViewSwitcher.ViewFactory() {@Overridepublic View makeView() {ImageView iv = new ImageView(MainActivity.this);iv.setImageResource(imgArray[currentImg]);return iv;}});}@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (v.getId()) {case R.id.imgSwitcher:if (event.getAction() == MotionEvent.ACTION_DOWN) {// 按下事件startTouchX = event.getX();return true;} else if (event.getAction() == MotionEvent.ACTION_UP) {// 抬起事件endTouchX = event.getX();// 手指抬起后判断手指的滑动方式if (endTouchX - startTouchX > 100) {//从左向右滑动//切换图片索引值currentImg = currentImg == 0 ? imgArray.length - 1 : currentImg - 1;//设置切换动画  从左侧进入imgSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_in_from_left));// 设置切换动画  从右侧退出imgSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_out_to_right));// 设置显示的图片imgSwitcher.setImageResource(imgArray[currentImg]);} else if (startTouchX - endTouchX > 100) {// 从右往左滑//切换图片索引值currentImg = currentImg == (imgArray.length-1) ? 0 : currentImg + 1;//设置切换动画  从右侧进入imgSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_in_from_right));// 设置切换动画  从左侧退出imgSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_out_to_left));// 设置显示的图片imgSwitcher.setImageResource(imgArray[currentImg]);}return true;}}return false;};
}

动画

左进入

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="300"android:fromXDelta="-100.0%p"android:toXDelta="0.0" /><alphaandroid:duration="300"android:fromAlpha="0.5"android:toAlpha="1.0" />
</set>

右进入

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="300"android:fromXDelta="100.0%p"android:toXDelta="0.0"/><alphaandroid:duration="300"android:fromAlpha="0.5"android:toAlpha="1.0"/>
</set>

左侧出

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="300"android:fromXDelta="0.0"android:toXDelta="-100.0%p" /><alphaandroid:duration="300"android:fromAlpha="1.0"android:toAlpha="0.5" />
</set>

右侧出

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:duration="300"android:fromXDelta="0.0"android:toXDelta="100.0%p" /><alphaandroid:duration="300"android:fromAlpha="1.0"android:toAlpha="0.5" />
</set>

网格视图进阶

适配器加载网格试图中的数据

适配器

  • ArrayList
  • Cursor

Adapter -> GridView

ArrayAdapter 数组适配器,通常用于将数组的多个值,包装成为多个列表项,元素为一行文字

SimpleAdapter 可自定义各种效果 数据源是array

SimpleCursorAdapter 将数据库的内容以列表的形式展现出来

BaseAdapter 对各个列表项进行定制

GridView组件

  • android:columnWidth=“100dp” 设置内部元素列宽度
  • android:gravity=“center” 设置内部元素的摆放方式
  • android:numColumns=“auto_fit” 设置列数 为自动分布
  • android:verticalSpacing=“5dp” /> 设置每个元素的纵向间距
  • android:horizontalSpacing=“5dp” /> 设置每个元素的横向间距

使用SimpleAdapter实现的网格

<?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"tools:context=".MainActivity"><GridViewandroid:id="@+id/gv1"android:layout_width="match_parent"android:layout_height="match_parent"android:numColumns="3" />
</LinearLayout>

cell.xml,网格元素对应的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:gravity="center"android:orientation="vertical"><ImageViewandroid:id="@+id/img"android:layout_width="100dp"android:layout_height="75dp" /></LinearLayout>
package com.liyanfeng.suwangge;import android.os.Bundle;
import android.widget.GridView;
import android.widget.SimpleAdapter;import androidx.appcompat.app.AppCompatActivity;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class MainActivity extends AppCompatActivity {private int[] imgArray = new int[]{R.drawable.h1,R.drawable.h2,R.drawable.h3,R.drawable.h4,R.drawable.h5,R.drawable.h6,R.drawable.h7,R.drawable.h8,R.drawable.h9,};private GridView gv1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeGridView();}private void initView() {gv1 = (GridView) findViewById(R.id.gv1);}private void makeGridView() {List<Map<String, Object>> listItem = new ArrayList<Map<String, Object>>();for (int i = 0; i <imgArray.length ; i++) {Map<String ,Object> mp = new HashMap<String, Object>();mp.put("image",imgArray[i]);listItem.add(mp);}SimpleAdapter sa = new SimpleAdapter(this, //上下文listItem,//  List<Map<String, Object>>R.layout.cell, // 布局文件new String[]{"image"},// List<Map<String, Object>> 中的Map的key字符串组成的列表new int[]{R.id.img}// 布局文件的view id);gv1.setAdapter(sa);}
}

使用BaseAdapter实现相册功能

<?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=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="QQ相册" /><GridViewandroid:id="@+id/grv"android:layout_width="match_parent"android:layout_height="match_parent"android:columnWidth="100dp"android:gravity="center"android:numColumns="auto_fit"android:verticalSpacing="5dp"android:horizontalSpacing="5dp"/></LinearLayout>
package com.liyanfeng.qqxiangce;import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private int[] pictureArray = new int[]{R.drawable.h1,R.drawable.h2,R.drawable.h3,R.drawable.h5,R.drawable.h5,R.drawable.h6,R.drawable.h7,R.drawable.h8,R.drawable.h9,R.drawable.h10,};private GridView grv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeGridView();}private void initView() {grv = (GridView) findViewById(R.id.grv);}private void makeGridView() {grv.setAdapter(new ImageAdapter(this));}// 通过BaseAdapter实现public class ImageAdapter extends BaseAdapter {private Context mContext;//构造方法public ImageAdapter(Context mContext) {this.mContext = mContext;}@Overridepublic int getCount() {// 返回图片数组长度return pictureArray.length;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}// 创建view@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ImageView iv;// 判断获取到的view是否为空if (convertView == null) {// 如果为空,创建一个ImageView组件iv = new ImageView(mContext);iv.setLayoutParams(new GridView.LayoutParams(100, 90));iv.setScaleType(ImageView.ScaleType.CENTER_CROP);// 设置图片的缩放方式为保持纵横比并且完全覆盖ImageView} else {iv = (ImageView) convertView;}iv.setImageResource(pictureArray[position]);return iv;}};
}

下拉列表框

Spinner

  • entries 属性指定数组资源,列表内容

数组资源需要定义Value

res/value/arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources><string-array name="ctype"><item>全部</item><item>选项B</item><item>选项C</item><item>选项D</item></string-array>
</resources>

如果不在布局文件中定义entries那么可以使用adapter来为列表添加内容

<?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=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/title" /><Spinnerandroid:id="@+id/spinner"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>
package com.liyanfeng.xialaleibiao;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {private String[] ctype;private Spinner spinner;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeSpinner();}private void initView() {spinner = (Spinner) findViewById(R.id.spinner);}private void makeSpinner() {ctype = new String[]{"全部","音乐","美术","体育"};// 创建ArrayAdapterArrayAdapter aa = new ArrayAdapter<String>(this,// 上下文android.R.layout.simple_spinner_item, //xml文件,这里是安卓内部定义的,可自定义ctype//字符串内容的数组);// 设置适配器的样式为 列表下拉  安卓内部定义的aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);spinner.setAdapter(aa);spinner.setOnItemSelectedListener(this);}@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {switch (parent.getId()) {case R.id.spinner:Log.i("改变", (String) spinner.getSelectedItem());break;}}@Overridepublic void onNothingSelected(AdapterView<?> parent) {}
}

列表视图

ListView

  • entries 对应数组资源文件

可以哦那个适配器设置内容

简单的字符串列表


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"tools:context=".MainActivity"><ListViewandroid:id="@+id/listview"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>
package com.liyanfeng.listshitu;import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private ListView listview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeListView();}private void initView() {listview = (ListView) findViewById(R.id.listview);}private void makeListView() {String[] con = new String[]{"吃","喝","玩","乐"};ArrayAdapter<String> aa = new ArrayAdapter<String>(this,//上下文android.R.layout.simple_list_item_1,//内置样式con//列表内容);listview.setAdapter(aa);}
}

简单的通讯录

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"tools:context=".MainActivity"><ListViewandroid:id="@+id/listview"android:layout_width="match_parent"android:layout_height="370dp" /></RelativeLayout>

res/layout/user.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="horizontal"><ImageViewandroid:id="@+id/img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:adjustViewBounds="true"android:maxWidth="72dp"android:maxHeight="72dp"android:paddingTop="10dp"android:paddingBottom="10dp" /><TextViewandroid:id="@+id/username"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:padding="10dp" />
</LinearLayout>
package com.liyanfeng.listshitu;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;import androidx.appcompat.app.AppCompatActivity;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {private ListView listview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeListView();}private void initView() {listview = (ListView) findViewById(R.id.listview);}private void makeListView() {int[] txArray = new int[]{R.drawable.t1,R.drawable.t2,R.drawable.t3,R.drawable.t4,};String[] usernameArray = new String[]{"张三","李四","王五","路六"};List<Map<String, Object>> objList = new ArrayList<Map<String, Object>>();for (int i = 0; i < txArray.length; i++) {Map<String, Object> mp = new HashMap<String, Object>();mp.put("image", txArray[i]);mp.put("username", usernameArray[i]);objList.add(mp);}SimpleAdapter sa = new SimpleAdapter(this,objList,R.layout.user,new String[]{"image", "username"},new int[]{R.id.img, R.id.username});listview.setAdapter(sa);// 添加事件listview.setOnItemClickListener(this);}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {switch (parent.getId()) {case R.id.listview:Map<String, Object> mp = (Map<String, Object>) parent.getItemAtPosition(position);Log.i("name", String.valueOf(mp.get("username")));Log.i("img", String.valueOf(mp.get("image")));break;}}
}

滚动视图

两种添加滚动视图的方法

  • xml
  • java

ScrollView 垂直滚动视图
HorizontalScrollView 水平滚动视图

注意: 在一个滚动视图中只能放一个组件,如果想放多个组件,那么需要一个布局管理器将多个组件包裹起来。

Java中

  1. ScrollView(Context)
  2. addView()
  3. 添加到布局管理器中

<?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:id="@+id/lineLayout"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"android:orientation="vertical"tools:context=".MainActivity"></LinearLayout>
package com.liyanfeng.gundongping;import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private LinearLayout lineLayout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeScrollView();}private void initView() {lineLayout = (LinearLayout) findViewById(R.id.lineLayout);}private void makeScrollView() {// 创建一个布局管理器LinearLayout ll2 = new LinearLayout(this);// 垂直布局ll2.setOrientation(LinearLayout.VERTICAL);// 创建滚动视图ScrollView sv = new ScrollView(this);// 滚动视图添加到根布局管理器lineLayout.addView(sv);// 新的线性布局管理器添加到滚动视图中sv.addView(ll2);// 创建一个图像视图ImageView iv = new ImageView(this);iv.setImageResource(R.drawable.img1);iv.setScaleType(ImageView.ScaleType.CENTER_CROP);ll2.addView(iv);TextView tv = new TextView(this);tv.setText(R.string.content);ll2.addView(tv);};
}

选项卡

不能使用指定的组件

  1. 在布局文件中添加TabHost TabWidget 和TabContent组件
  2. 编写各个标签页的xml布局文件
  3. 获取并初始化TabHost组件
  4. 将TabHost添加到标签页

xml 中 TabHost TabWidget FrameLayout 这三个的id是固定的 述写法也是固定的

<?xml version="1.0" encoding="utf-8"?>
<TabHost 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:id="@android:id/tabhost"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TabWidgetandroid:id="@android:id/tabs"android:layout_width="match_parent"android:layout_height="wrap_content"></TabWidget><FrameLayoutandroid:id="@android:id/tabcontent"android:layout_width="match_parent"android:layout_height="match_parent"></FrameLayout></LinearLayout></TabHost>

tab1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:id="@+id/left"android:orientation="vertical"android:gravity="center"android:layout_height="match_parent"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/t1" /></LinearLayout>

tab2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/right"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/t5" /></LinearLayout>
package com.liyanfeng.biaoqianye;import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.TabHost;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private TabHost tabhost;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();makeTabView();}private void initView() {tabhost = (TabHost) findViewById(android.R.id.tabhost);}private void makeTabView() {// 初始化TabHosttabhost.setup();// 生成布局填充器LayoutInflater inflater = LayoutInflater.from(this);// 添加标签页tab1 到 tabhost中inflater.inflate(R.layout.tab1, //标签子页的布局文件tabhost.getTabContentView()//tabHost的tabContent);// 添加标签页tab2 到 tabhost中inflater.inflate(R.layout.tab2,tabhost.getTabContentView());// 指定 tag  indicator 子页面中 根布局管理器的idtabhost.addTab(tabhost.newTabSpec("tb1").setIndicator("left").setContent(R.id.left));tabhost.addTab(tabhost.newTabSpec("tb2").setIndicator("right").setContent(R.id.right));}
}

安卓日记 二 UI组件相关推荐

  1. 安卓学习总结-UI开发流程

    最近做的工作,主要是对安卓的一系列UI组件的开发,在完成设计需求的过程中,对UI开发流程有了一点小想法,今天来把他们总结一下. UI开发流程图 一.了解安卓中的View体系 在UI开发的过程中,我们一 ...

  2. android 界面组件,安卓开发学习周第三篇——Android中的UI组件

    原标题:安卓开发学习周第三篇--Android中的UI组件 在Android APP中,所有的用户界面元素都是由View和ViewGroup的对象构成的.View是绘制在屏幕上的用户能与之交互的一个对 ...

  3. 【Vue学习】—Vue UI组件库(二十八)

    [Vue学习]-Vue UI组件库(二十八) 一.移动端常用的UI组件库 二.PC端常用的UI组件库 三.具体使用自行查看文档,这里就不做概述了

  4. Element UI 组件库分析和二次开发(一)

    我的本地开发环境:M1 芯片Mac,node v12.22.10. 一.Element UI 组件库二次开发的大致流程 1. 从 Element 官方 clone 一份 dev 源码到本地 2. 安装 ...

  5. Chrome学习笔记(二):UI组件,皮肤引擎

    原创文章,转载请注明:转载自Soul Apogee 本文链接地址:Chrome学习笔记(二):UI组件,皮肤引擎 -- 基础设施篇 Chrome的UI是很奇妙的,因为看起来能很好的跨平台,而且可以很好 ...

  6. UI组件之TextView及其子类(二)RadioButton和CheckBox

    单选按钮(RadioButton)和复选框(CheckBox),状态开关按钮(ToggleButton),开关(Switch)都是普通的UI组件,都继承了Button类,因此都可以用Button的各种 ...

  7. 安卓高德地图-(定位+离线UI组件自定义1)

    效果图: 其中第二张图是官网默认的,后面有讲解如何自己定义界面. STEP1: 先去高德开放平台注册账号,网址:http://lbs.amap.com/ 之后再去控制台-应用管理找到自己的key,如下 ...

  8. 疯狂Android讲义(二)——第二部分:第1组UI组件(布局管理器)

    一.第1组UI组件:布局管理器 Android 的界面组件比较多,不利于掌握它们内在的关系.为了帮助读者更好地掌握Android界面组件的关系,本书将会把这些界面组件按照它们的关联分析,分为几组进行介 ...

  9. UI组件库Kendo UI for Vue中文入门指南(二)

    在本文中,您将通过构建一个包含 Grid.DropDownList.Window 和设计主题的小应用程序来学习如何使用Kendo UI for Vue组件. Kendo UI最新官方正式版下载 5. ...

最新文章

  1. string获取 倒数 下标_Redis系列:Redis字符串(STRING)介绍
  2. 2018-2019-1 20189210 《LInux内核原理与分析》第六周作业
  3. 从二分类到多分类的迁移策略
  4. 多元统计分析最短距离法_多元统计分析重点
  5. 使用libxml提示libxml/tree.h找不到的问题解决
  6. 该文件可能是只读的 或者您要访问的位置_喔噢小贴士:如何保护PPT不被更改,将其设为只读...
  7. linux命令 sed 有的功能有,Linux命令:sed简介
  8. java实现linux变量替换_linux java 配置 含环境变量 | 学步园
  9. ajax跨越html,ajax跨域的解决方案
  10. catia2017安装包打开没反应_CATIA V5-6R2017软件下载与安装教程
  11. (转)互利主义:道德经济人的基本行为准则
  12. pdf如何解除限制转换为word
  13. 详解神奇的卡尔曼滤波(Kalman filter)算法
  14. hcse5.0全套PPT档
  15. 输入输入是否为回文(如“abcba”和”123321”都是回文)。(c语言)
  16. 华勤技术股份有限公司
  17. 墙裂推荐6个优质公众号
  18. win10专业版电脑不能局域网访问win10家庭版
  19. python创意turtle作品大白-Python turtle 画个大白
  20. 第四十二篇:Flink面试方案设计篇

热门文章

  1. Eclipse代码补全,修改 空格键 = 键不上屏
  2. python3学习(3):ID 遍历爬虫
  3. sensor的高像素和大像素优劣分析
  4. 全国计算机一级学科点数量,最新数据:39所985高校一级学科博士点数量!
  5. 火车轨道铁路轨道检测识别(附带Python源码+详细解析)
  6. (ICLR-2022)关于局部注意力和动态深度卷积之间的联系
  7. 笔记本 win7 不能待机 不能休眠
  8. “新闻拉盘币”Enjin背后到底有没有干货
  9. 一起来看看压敏电阻器的电路防护作用吧!
  10. FFmpeg命令详解