ScrollView是继承于FrameLayout,也是一个显示容器,由于手机屏幕是有限的,当需要组件安排多组信息的时候,ScrollView可以安排这些组件,我们浏览的时候可以进行滑动操作,滚动显示。但是,需要注意的是,ScrollView只能包含一种组件。
实现代码:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrollview);
tv_scrollview_show = (TextView) findViewById(R.id.tv_show);
btn_to_top = (Button) findViewById(R.id.btn_to_top);
btn_to_bottom = (Button) findViewById(R.id.btn_to_bottom);
scrollView = (ScrollView) findViewById(R.id.sc);
initData();
btn_to_top.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scrollView.fullScroll(ScrollView.FOCUS_UP);
}
});
btn_to_bottom.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
private void initData() {
StringBuffer buffer = new StringBuffer();
for (int i = 1; i < 120; i++) {
buffer.append("这是第" + i + "个条目" + "\n");
}
tv_scrollview_show.setText(buffer.toString());
}
效果图:
ScrollView就介绍到这里,这个不是很常用。
进度条在很多场景下都需要用到,在进行一些耗时操作,如果不做进度显示,用户会以为应用ANR,给用户造成不好的体验,所以需要用到进度条。Android系统提供的进度条ProgressBar继承于View,有如下的属性:
android:max:进度条的最大值
android:progress:进度条已完成进度
android:progressDrawable:设置轨道对应的Drawable对象
android:indeterminate:如果设置成true,则进度条不精确显示进度
android:indeterminateDrawable:设置不显示进度的进度条的Drawable对象
android:indeterminateDuration:设置不精确显示进度的持续时间
android:secondaryProgress:二级进度条,类似于视频播放的一条是当前播放进度,一条是缓冲进度,前者通过progress属性进行设置!
对应Java方法有:
getMax():获取这个进度条的上限
getProgress():获取到当前进度
getSecondaryProgress():获取次要进度
incrementProgressBy(int diff):指定增加的进度
isIndeterminate():指示进度条是否处于不确定模式
setIndeterminate(boolean indeterminate):设置进度条进入不确定模式
系统提供的进度条在这里就不多介绍了,比较简单,下面是自定义进度条的例子:
package com.example.hello_baseui.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
import com.example.hello_baseui.R;
/**
* Created by Administrator on 2016/6/29.
*/
public class CircleProgressBar extends View {
/**
* 画笔对象的引用
*/
private Paint paint;
/**
* 圆环的颜色
*/
private int circleColor;
/**
* 圆环进度的颜色
*/
private int circleProgressColor;
/**
* 中间进度百分比的字符串的颜色
*/
private int textColor;
/**
* 中间进度百分比的字符串的字体大小
*/
private float textSize;
/**
* 圆环的宽度
*/
private float circleWidth;
/**
* 最大进度
*/
private int max;
/**
* 当前进度
*/
private int progress;
/**
* 是否显示中间的进度
*/
private boolean isShowProgressText;
/**
* 进度的风格,实心或者空心
*/
private int circleStyle;
private float strokeWidth;
/**
* 空心
*/
public static final int STROKE = 0;
/**
* 实心
*/
public static final int FILL = 1;
/**
* 构造器
*
* @param context
*/
public CircleProgressBar(Context context) {
this(context, null);
}
/**
* 构造器
*
* @param context
* @param attrs
*/
public CircleProgressBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* 构造器
*
* @param context
* @param attrs
* @param defStyleAttr
*/
public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context, attrs);
}
/**
* 初始化组件
*
* @param context
* @param attrs
*/
private void initView(Context context, AttributeSet attrs) {
paint = new Paint();
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
circleColor = mTypedArray.getColor(R.styleable.CircleProgressBar_circleColor, Color.RED);
circleProgressColor = mTypedArray.getColor(R.styleable.CircleProgressBar_circleProgressColor, Color.BLUE);
textColor = mTypedArray.getColor(R.styleable.CircleProgressBar_textColor, Color.BLUE);
textSize = mTypedArray.getDimension(R.styleable.CircleProgressBar_textSize, 14);
circleWidth = mTypedArray.getDimension(R.styleable.CircleProgressBar_circleWidth, 10);
isShowProgressText = mTypedArray.getBoolean(R.styleable.CircleProgressBar_isShowProgressText, true);
circleStyle = mTypedArray.getInt(R.styleable.CircleProgressBar_circleStyle, 0);
mTypedArray.recycle();
}
/**
* 绘制
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制最外层的大圆
int centre = getWidth() / 2; //获取圆心的x坐标
int radius = (int) (centre - circleWidth / 2) - 2; //圆环的半径
paint.setColor(circleColor);
paint.setStyle(Paint.Style.STROKE);//设置为空心
paint.setStrokeWidth(strokeWidth); //设置圆环的宽度
paint.setAntiAlias(true);//消除锯齿
canvas.drawCircle(centre, centre, radius, paint); //画出圆环
//===========================================================
//绘制进度的百分比
paint.setStrokeWidth(0);
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体
int percent = (int) (((float) progress / (float) max) * 100); //中间的进度百分比,先转换成float在进行除法运算,不然都为0
float textWidth = paint.measureText(percent + "%"); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
if (isShowProgressText && circleStyle == STROKE) {
canvas.drawText(percent + "%", centre - textWidth / 2, centre + textSize / 2, paint); //画出进度百分比
}
//============================================================================
//绘制圆弧和进度
paint.setStrokeWidth(strokeWidth); //设置圆环的宽度
paint.setColor(circleProgressColor); //设置进度的颜色
RectF oval = new RectF(centre - radius - 1, centre - radius - 1, centre + radius + 1, centre + radius + 1); //用于定义的圆弧的形状和大小的界限
switch (circleStyle) {
case STROKE: {
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 90, 360 * progress / max, false, paint); //根据进度画圆弧
break;
}
case FILL: {
paint.setStyle(Paint.Style.FILL_AND_STROKE);
if (progress != 0)
canvas.drawArc(oval, 90, 360 * progress / max, true, paint); //根据进度画圆弧
break;
}
}
}
//==============================get and set========================
/**
* 设置进度的最大值
*
* @param max
*/
public synchronized void setMax(int max) {
if (max < 0) {
throw new IllegalArgumentException("The max cannot less than 0");
}
this.max = max;
}
public synchronized int getMax() {
return max;
}
/**
* 获取进度.需要同步
*
* @return
*/
public synchronized int getProgress() {
return progress;
}
/**
* 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
* 刷新界面调用postInvalidate()能在非UI线程刷新
*
* @param progress
*/
public synchronized void setProgress(int progress) {
if (progress < 0) {
throw new IllegalArgumentException("The progress cannot less then 0");
}
if (progress > max) {
progress = max;
}
if (progress <= max) {
this.progress = progress;
postInvalidate();
}
}
public int getCircleColor() {
return circleColor;
}
/**
* 设置圆环的颜色
*
* @param circleColor
*/
public void setCircleColor(int circleColor) {
this.circleColor = circleColor;
}
public int getTextColor() {
return textColor;
}
/**
* 设置圆环字体的颜色
*
* @param textColor
*/
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public float getTextSize() {
return textSize;
}
/**
* 设置圆环字体的大小
*
* @param textSize
*/
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public float getCircleWidth() {
return circleWidth;
}
/**
* 设置圆的宽度
*
* @param circleWidth
*/
public void setCircleWidth(float circleWidth) {
this.circleWidth = circleWidth;
}
public boolean isShowProgressText() {
return isShowProgressText;
}
/**
* 设置是否显示进度百分比
*
* @param showProgressText
*/
public void setShowProgressText(boolean showProgressText) {
isShowProgressText = showProgressText;
}
public int getCircleStyle() {
return circleStyle;
}
/**
* 设置圆环的样式,空心和实心
*
* @param circleStyle
*/
public void setCircleStyle(int circleStyle) {
this.circleStyle = circleStyle;
}
public float getStrokeWidth() {
return strokeWidth;
}
/**
* 设置绘制圆环的宽度
* @param strokeWidth
*/
public void setStrokeWidth(float strokeWidth) {
this.strokeWidth = strokeWidth;
}
public int getCircleProgressColor() {
return circleProgressColor;
}
/**
* 设置绘制圆环进度的颜色
* @param circleProgressColor
*/
public void setCircleProgressColor(int circleProgressColor) {
this.circleProgressColor = circleProgressColor;
}
//==============================get and set========================
}
使用例子:
布局文件代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android_custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.hello_baseui.widget.CircleProgressBar
android:id="@+id/cpb"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android_custom:circleColor="#D1D1D1"
android_custom:textSize="20sp" />
</LinearLayout>
Java代码:
private CircleProgressBar circleProgressBar;
int progressStatus = 0;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progressbar);
circleProgressBar = (CircleProgressBar) findViewById(R.id.cpb);
circleProgressBar.setMax(100);
circleProgressBar.setCircleWidth(30);
circleProgressBar.setStrokeWidth(10);
circleProgressBar.setCircleProgressColor(Color.BLUE);
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
circleProgressBar.setProgress(progressStatus);
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
while (progressStatus < 100) {
progressStatus += 3;
try {
Thread.sleep(1000);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
实现效果图:
一些长方形的进度条
SeekBar是ProgressBar的子类,ProgressBar里面的属性SeekBar都能用。SeekBar类似于ProgressBar,但是SeekBar可以允许用户拖动改变进度,我们可以将它用户多媒体播放,下面介绍一下SeekBar,实现一个简单的例子:
布局文件代码:
<SeekBar
android:id="@+id/sb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp" />
<TextView
android:id="@+id/tv_seek_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
java代码:
private SeekBar sb;
private TextView textView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seekbar);
sb = (SeekBar) findViewById(R.id.sb);
textView = (TextView) findViewById(R.id.tv_seek_bar);
textView.setMovementMethod(ScrollingMovementMethod.getInstance());//设置文字可以滚动
//设置SeekBar事件监听,需要实现三个方法
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
/**
* 拖动操作
* @param seekBar
* @param i
* @param b
*/
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
textView.setText("正在拖动,拖动了:" + sb.getProgress() + "\n");
}
/**
* 刚开始拖动
* @param seekBar
*/
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
textView.setText("开始拖动,拖动了:" + sb.getProgress() + "\n");
}
/**
* 停止拖动
* @param seekBar
*/
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
textView.setText("停止拖动了,已经拖动了:" + sb.getProgress() + "\n");
}
});
}
实现的效果图:
关于SeekBar就简单介绍到这里。Android系统常用的UI就介绍到这里,下面我们介绍一下Android的五大布局
下面这些是国内镜像的API
ScrollView滚动视图
SeekBar拖动条
ProgressBar进度条
这是例子源码