Android 高级UI组件
文章目录
1. 进度条 ProgressBar
ProgressBar
,进度条,分为长条形进度条(确定操作耗时时使用)和圆形进度条(不确定操作耗时时使用)。默认样式是圆形进度条。
使用举例:
<ProgressBar
android:id="@+id/indeterminateBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
-
要使用长条形进度条:
-
设置
style
属性:style="@android:style/Widget.ProgressBar.Horizontal"
-
设置进度条的进度:
android:progress="25"
表示当前进度为25%的条形进度条。
<ProgressBar android:id="@+id/determinateBar" style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:progress="25"/>
默认情况下进度条的进度最大值为100,可以通过
android:max
属性修改。
-
-
基本使用:在另外一个线程中检测耗时操作是否完成,没有完成时,更新进度条;完成时,隐藏进度条。
-
由于Android不支持在主线程中更新UI组件,所以更新进度条要使用安卓提供的
Handle
对象用来发送消息,更新UI
举例:
package com.mingrisoft;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.util.logging.LogRecord;
public class MainActivity extends Activity {
private ProgressBar horizonP; //水平进度条
private int mProgressStatus = 0; //完成进度
private Handler mHandler; //声明一个用于处理消息的Handler类的对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); //设置全屏显示
horizonP = (ProgressBar) findViewById(R.id.progressBar1); //获取水平进度条
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0x111) {
horizonP.setProgress(mProgressStatus); //更新进度
} else {
Toast.makeText(MainActivity.this, "耗时操作已经完成", Toast.LENGTH_SHORT).show();
horizonP.setVisibility(View.GONE); //设置进度条不显示,并且不占用空间
}
}
};
new Thread(new Runnable() {
public void run() {
while (true) {
mProgressStatus = doWork(); //获取耗时操作完成的百分比
Message m = new Message();
if (mProgressStatus < 100) {
m.what = 0x111;
mHandler.sendMessage(m); //发送信息
} else {
m.what = 0x110;
mHandler.sendMessage(m); //发送消息
break;
}
}
}
//模拟一个耗时操作
private int doWork() {
mProgressStatus += Math.random() * 10; //改变完成进度
try {
Thread.sleep(200); //线程休眠200毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
return mProgressStatus; //返回新的进度
}
}).start(); //开启一个线程
}
}
2. 拖动条 SeekBar
SeekBar
,拖动条,是ProgressBar
的子类。
除了继承过来的属性,还有一个特殊的属性:
-
android:thumb
设置拖动条上的"小圆点"的样式。
使用举例:
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"
android:progress="255"
/>
- 可以通过设置
SeekBar.OnSeekBarChangeListener
,来监听进度条变化。
举例:
package com.mingrisoft;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.SeekBar;
public class MainActivity extends AppCompatActivity {
private ImageView image; //定义图片
private SeekBar seekBar; //定义拖动条
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.image); //获取图片
seekBar = (SeekBar) findViewById(R.id.seekbar); //获取拖动条
//为拖动条设置监听事件
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
// 当拖动条的滑块位置发生改变时触发该方法
@Override
public void onProgressChanged(SeekBar arg0, int progress,
boolean fromUser) {
// 动态改变图片的透明度
image.setImageAlpha(progress);
}
@Override
public void onStartTrackingTouch(SeekBar bar) {
// 开始触摸时执行
}
@Override
public void onStopTrackingTouch(SeekBar bar) {
// 停止触摸时执行
}
});
}
}
3. 星级评分条 RatingBar
RatingBar
,星级评分条,也是ProgressBar
的子类,组件宽度需设置为wrap_content
。
主要属性:
属性 | 说明 |
---|---|
android:isIndicator |
是否是不可交互,值为true 或者false |
android:numStars |
星星的数量 |
android:rating |
设置的评级 |
android:stepSize |
评级的步长,默认为0.5,因此可以选择半颗星星 |
使用举例:
<!-- 星级评分条 -->
<RatingBar
android:id="@+id/ratingBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:rating="0"
android:layout_above="@+id/btn"
android:layout_marginBottom="60dp"/>
-
Java中可以使用
<RatingBar>.setRatting(<int ratting>)
或<RatingBar>.getRatting(<int ratting>)
来设置或获取当前评级。 -
使用
<RatingBar>.setOnRatingBarChangeListener()
来设置监听。
4. 显示图像组件 ImageView
ImageView
,用以显示图像。
使用举例:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/my_image"
android:contentDescription="@string/my_image_description"
/>
</LinearLayout>
常用属性:
属性 | 说明 |
---|---|
android:maxHeight |
最大高度 |
android:maxWidth |
最大宽度 |
android:adjustViewBounds |
设置保持图片纵横比,调整View的边界。若要maxHeight 和maxWidth 属性生效,则该属性需设置为true |
android:scaleType |
控制图片如何适配ImageView 的尺寸大小 |
android:src |
设置图片资源 |
android:tint |
对图像进行着色 |
5. 图像切换显示 ImageSwitcher
ImageSwitcher
,用以切换显示图片。
使用举例:
<ImageSwitcher
android:id="@+id/imageswitcher"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
-
为
ImageSwicher
设置Factory
(用来为ImageSwicher
制造ImageView
):<imageSwitcher>.setFactory()
-
为
ImageSwicher
设置触摸监听器:imageSwitcher.setOnTouchListener()
-
设置图片资源:
<imageSwitcher>.setImageRecource(<int RecourceID>)
举例:实现相册(滑动切换图片)
package com.mingrisoft;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher;
public class MainActivity extends Activity {
private int[] arrayPictures = new int[]{
R.mipmap.img01, R.mipmap.img02, R.mipmap.img03,
R.mipmap.img04, R.mipmap.img05, R.mipmap.img06,
R.mipmap.img07, R.mipmap.img08, R.mipmap.img09,
};// 声明并初始化一个保存要显示图像ID的数组
private ImageSwitcher imageSwitcher; // 声明一个图像切换器对象
//要显示的图片在图片数组中的Index
private int pictutureIndex;
//左右滑动时手指按下的X坐标
private float touchDownX;
//左右滑动时手指松开的X坐标
private float touchUpX;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏显示
imageSwitcher = (ImageSwitcher) findViewById(R.id.imageswitcher); // 获取图像切换器
//为ImageSwicher设置Factory,用来为ImageSwicher制造ImageView
imageSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
@Override
public View makeView() {
ImageView imageView = new ImageView(MainActivity.this); // 实例化一个ImageView类的对象
imageView.setImageResource(arrayPictures[pictutureIndex]);//根据id加载默认显示图片
return imageView; // 返回imageView对象
}
});
imageSwitcher.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//取得左右滑动时手指按下的X坐标
touchDownX = event.getX();
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
//取得左右滑动时手指松开的X坐标
touchUpX = event.getX();
//从左往右,看下一张
if (touchUpX - touchDownX > 100) {
//取得当前要看的图片的index
pictutureIndex = pictutureIndex == 0 ? arrayPictures.length - 1 : pictutureIndex - 1;
//设置图片切换的动画
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_in_left));
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_out_right));
//设置当前要看的图片
imageSwitcher.setImageResource(arrayPictures[pictutureIndex]);
//从右往左,看上一张
} else if (touchDownX - touchUpX > 100) {
//取得当前要看的图片index
pictutureIndex = pictutureIndex == arrayPictures.length - 1 ? 0 : pictutureIndex + 1;
//设置切换动画
imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_out_left));
imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.slide_in_right));
//设置要看的图片
imageSwitcher.setImageResource(arrayPictures[pictutureIndex]);
}
return true;
}
return false;
}
});
}
}
6. 网格视图组件 GridView
GridView
,网格形式显示组件,网格内数据通过Adapter
将后端数据传向UI界面,样式通过单独的布局文件配置
Adapter
:适配器,是后端数据和UI界面间的重要桥梁,复杂为数据集中的每个数据设置一个View。
常用Adapter
:
-
ArrayAdapter
数组适配器,将数组的多个值包装成多个列表项,只能显示一行文字
-
SmipleAdapter
简单适配器,将
List
的多个值包装成列表项,可以自定义各种效果 -
SimpleCursorAdapter
将数据库的数据包装成列表项
-
BaseAdapter
基础适配器,自定义功能强大
GirdView
主要属性:
属性 | 说明 |
---|---|
android:columnWidth |
列宽 |
android:gravity |
每个单元格内的摆放方式 |
android:horizontalSpacing |
水平间距 |
android:numColumns |
列数 |
android:verticalSpacing |
垂直间距 |
android:stretchMode |
延申方式 |
使用举例:
<!--网格布局-->
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="100dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="5dp">
<GridView>.setAdapter(<Adapter adapter>)
:设置Adapter
举例:
package com.mingrisoft;
import android.app.Activity;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class MainActivity extends Activity {
//显示的图片数组
private Integer[] picture = {
R.mipmap.img01, R.mipmap.img02, R.mipmap.img03,
R.mipmap.img04, R.mipmap.img05, R.mipmap.img06, R.mipmap.img07,
R.mipmap.img08, R.mipmap.img09, R.mipmap.img10, R.mipmap.img11,
R.mipmap.img12,};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridView= (GridView) findViewById(R.id.gridView); //获取布局文件中的GridView组件
gridView.setAdapter(new ImageAdapter(this)); //调用ImageAdapter
}
//创建ImageAdapter
public class ImageAdapter extends BaseAdapter{
private Context mContext; //获取上下文
public ImageAdapter(Context c){
mContext=c;
}
@Override
public int getCount() {
return picture.length;//图片数组的长度
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if(convertView==null){
//判断传过来的值是否为空
imageView=new ImageView(mContext); //创建ImageView组件
imageView.setLayoutParams(new GridView.LayoutParams(100, 90)); //为组件设置宽高
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); //选择图片铺设方式
}else{
imageView= (ImageView) convertView;
}
imageView.setImageResource(picture[position]); //将获取图片放到ImageView组件中
return imageView; //返回ImageView
}
}
}
7. 下拉列表框 Spinner
Spinner
, 显示下拉列表。
使用举例:
<Spinner
android:id="@+id/planets_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
可以使用array
资源文件xml
来定义要在这个下拉列表中填充的数据。在res/values
下新建array.xml
文件,内容举例如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="planets_array">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
<item>Mars</item>
<item>Jupiter</item>
<item>Saturn</item>
<item>Uranus</item>
<item>Neptune</item>
</string-array>
</resources>
随后设置属性android:entries
为array/planets_arra
即可。
当然也可以通过Adapter
,用Java代码的形式设置
package com.mingrisoft;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = (Spinner) findViewById(R.id.spinner); //获取下拉列表
/****************通过指定适配器的方式为选择列表框指定列表项********************/
// 方法一
// String[] ctype=new String[]{"全部","电影","图书","唱片","小事","用户","小组","群聊","游戏","活动"}
// ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,ctype);
// 方法二
// ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
// this, R.array.ctype,android.R.layout.simple_dropdown_item_1line); //创建一个适配器
//
// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // 为适配器设置列表框下拉时的选项样式
// spinner.setAdapter(adapter); // 将适配器与选择列表框关联
/***************************************************************************/
//为下拉列表创建监听事件
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String result = parent.getItemAtPosition(position).toString(); //获取选择项的值
Toast.makeText(MainActivity.this,result,Toast.LENGTH_SHORT).show(); //显示被选中的值
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
}
8. 列表视图 ListView
ListView
,列表显示。
使用举例:
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
-
可以通过
andoroid:entries
属性指定列表项 -
也可以通过适配器:
<ListView>.setAdapter()
举例:
package com.mingrisoft;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listview = (ListView) findViewById(R.id.listview); // 获取列表视图
int[] imageId = new int[]{
R.mipmap.img01, R.mipmap.img02, R.mipmap.img03,
R.mipmap.img04, R.mipmap.img05, R.mipmap.img06,
R.mipmap.img07, R.mipmap.img08, R.mipmap.img09,
}; // 定义并初始化保存图片id的数组
String[] title = new String[]{
"刘一", "陈二", "张三", "李四", "王五",
"赵六", "孙七", "周八", "吴九"}; // 定义并初始化保存列表项文字的数组
List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>(); // 创建一个list集合
// 通过for循环将图片id和列表项文字放到Map中,并添加到list集合中
for (int i = 0; i < imageId.length; i++) {
Map<String, Object> map = new HashMap<String, Object>(); // 实例化Map对象
map.put("image", imageId[i]);
map.put("名字", title[i]);
listItems.add(map); // 将map对象添加到List集合中
}
SimpleAdapter adapter = new SimpleAdapter(this, listItems,
R.layout.main, new String[] {
"名字", "image" }, new int[] {
R.id.title, R.id.image }); // 创建SimpleAdapter
listview.setAdapter(adapter); // 将适配器与ListView关联
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Map<String, Object> map = ( Map<String, Object> )parent.getItemAtPosition(position); //获取选择项的值
Toast.makeText(MainActivity.this,map.get("名字").toString(),Toast.LENGTH_SHORT).show();
}
});
}
}
9. 滚动视图 ScrollView
ScrollVView
,滚动视图,垂直方向滚动(水平方向使用:HorizontalScrollView
)。
使用举例:
<ScrollView
android:layout_width="match_parent"
andorid:layout_height="wrap_content">
</ScrollView>
- 内部只能由一个子标签,因此需要多个组件时,需要使用布局
Layout
进行嵌套。
举例:
package com.mingrisoft;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
LinearLayout linearLayout, linearLayout2;//定义linearLayout为默认布局管理器,linearLayout2为新建布局管理器
ScrollView scrollView;//定义滚动视图组件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout = (LinearLayout) findViewById(R.id.ll);//获取布局管理器
linearLayout2 = new LinearLayout(MainActivity.this);//创建一个新的布局管理器
linearLayout2.setOrientation(LinearLayout.VERTICAL);//设置为纵向排列
scrollView = new ScrollView(MainActivity.this);//创建滚动视图组件
scrollView.addView(linearLayout2);//滚动视图组件中添加新建布局
linearLayout.addView(scrollView);//默认布局中添加滚动视图组件
ImageView imageView = new ImageView(MainActivity.this);//创建ImageView组件
imageView.setImageResource(R.mipmap.cidian);//ImagView添加图片
TextView textView = new TextView(MainActivity.this);//创建TextView组件
textView.setText(R.string.cidian);//TextView添加文字
linearLayout2.addView(imageView);//新建布局中添加ImageView组件
linearLayout2.addView(textView);//新建布局中添加TextView组件
}
}
<ScrollView>.addView()
:添加布局
10. 选项卡
既多标签页。
添加步骤:
-
在布局文件中添加
TabHost
,TabWidget
,TabContent
(使用FrameLayout
)组件。-
TabHost
的id
使用固定值:@android:id/tabhost
-
<TabHost>
中添加LinearLayout
布局管理器,用以添加TabWidget
,TabContent
。 -
LinearLayout
布局管理中,添加TabWidget
,id
使用固定值:@android:id/tabs
-
LinearLayout
布局管理中,添加FrameLayout
布局管理器,id
使用固定值:@android:id/tabcontent
使用举例:
<?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.mingrisoft.MainActivity"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TabWidget android:id="@android:id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content"/> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </LinearLayout> </TabHost>
-
-
编写各标签页的布局文件。
-
获取并初始化
TabHost
组件。-
获取
TabHost
:tabHost = (TabHost) findViewById(android.R.id.tabhost);//获取TabHost对象
-
初始化
TabHost
:tabHost.setup();//初始化TabHost组件
-
-
为
TabHost
对象添加标签页。-
声明
LayoutInflater
对象,加载布局资源:LayoutInflater inflater = LayoutInflater.from(this); // 声明并实例化一个LayoutInflater对象 inflater.inflate(<布局资源id,如R.layout.tab1>, tabHost.getTabContentView());
-
添加标签页
<tabHost>.addTab(tabHost.newTabSpec("<tab规范化名称,非空,如t>") .setIndicator("<标签名称>") .setContent(<布局id,如R.id.liL1>));
-