TextView显示一行
TextView及直接父类控件属性layout_height
android:layout_height="wrap_content/match_parent"//内容只显示一行/内容完全展示
SwipeRefreshLayout布局中添加 CircleView布局
android.support.v4.widget.SwipeRefreshLayout.java
{
public SwipeRefreshLayout(Context context, AttributeSet attrs) {
//构造方法中调用createProgressView函数
createProgressView();
}
private void createProgressView() {
mCircleView = new CircleImageView(getContext(), CIRCLE_BG_LIGHT, CIRCLE_DIAMETER/2);
mProgress = new MaterialProgressDrawable(getContext(), this);
mProgress.setBackgroundColor(CIRCLE_BG_LIGHT);
mCircleView.setImageDrawable(mProgress);
//添加布局时是隐藏状态
mCircleView.setVisibility(View.GONE);
//把子视图添加到该布局中
addView(mCircleView);
}
}
显示CircleView布局
有两处显示CircleView布局
android.support.v4.widget.SwipeRefreshLayout.java
{
/**
*该函数是一个Public函数
*该函数是给外部提供的
*唯一一个调用startScaleUpAnimation函数的函数
*/
public void setRefreshing(boolean refreshing) {
}
/**
*该函数是一个私有函数,说明有能被该类中的函数调用
*该函数显示CircleView布局
*/
private void startScaleUpAnimation(AnimationListener listener) {
//<1>显示CircleView布局
mCircleView.setVisibility(View.VISIBLE);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
//ACTION_MOVE在下滑的过程中才会显示CircleView布局
case MotionEvent.ACTION_MOVE: {
//布尔变量mIsBeingDragged为true才会显示CircleView布局
if (mIsBeingDragged) {
// where 1.0f is a full circle
//<2>显示CircleView视图
if (mCircleView.getVisibility() != View.VISIBLE) {
mCircleView.setVisibility(View.VISIBLE);
}
break;
}
}
}
mIsBeingDragged布尔变量
android.support.v4.widget.SwipeRefreshLayout.java
{
//开始往下拽的标识,默认值为false.
private boolean mIsBeingDragged;
//手指按下去的点的y坐标
private float mInitialDownY;
private int mTouchSlop;
public SwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
//ViewConfiguration.getScaledTouchSlop();触发移动事件的最小距离
//自定义View处理touch事件的时候,有的时候需要判断用户是否真的存在movie
//系统提供了这样的方法。表示滑动的时候,手的移动要大于这个返回的距离值才开始移动控件。
//int TOUCH_SLOP = 8;
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (action) {
case MotionEvent.ACTION_DOWN: {
mIsBeingDragged = false;
//按下时点的y坐标
final float initialDownY = getMotionEventY(ev, mActivePointerId);
mInitialDownY = initialDownY;
}
break;
case MotionEvent.ACTION_MOVE:{
//移动过程中点的y坐标
final float y = getMotionEventY(ev, mActivePointerId);
final float yDiff = y - mInitialDownY;
if (yDiff > mTouchSlop && !mIsBeingDragged) {
//下拉到一定的距离,并且还没有显示
mIsBeingDragged = true;
}
break;
}
}
CircleView布局随着滑动位置发生变化
布局函数onLayout()
(width / 2 - circleWidth / 2)
mCurrentTargetOffsetTop
width / 2 + circleWidth / 2
mCurrentTargetOffsetTop + circleHeight
这里唯一发生变化的是变量mCurrentTargetOffsetTop
android.support.v4.widget.SwipeRefreshLayout.java
{
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int circleWidth = mCircleView.getMeasuredWidth();
int circleHeight = mCircleView.getMeasuredHeight();
mCircleView.layout((width / 2 - circleWidth / 2), mCurrentTargetOffsetTop,
(width / 2 + circleWidth / 2), mCurrentTargetOffsetTop + circleHeight);
}
}
测量函数
android.support.v4.widget.SwipeRefreshLayout.java
{
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mCircleView.measure(MeasureSpec.makeMeasureSpec(mCircleWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mCircleHeight, MeasureSpec.EXACTLY));
if (!mUsingCustomStart && !mOriginalOffsetCalculated) {
mOriginalOffsetCalculated = true;
mCurrentTargetOffsetTop = mOriginalOffsetTop = -mCircleView.getMeasuredHeight();
}
}
}
CircleView布局以缩减的方式消失
PullRefreshLayout.java {
private void startScaleDownAnimation(Animation.AnimationListener listener) {
mScaleDownAnimation = new Animation() {
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
setAnimationProgress(1 - interpolatedTime);
}
};
mScaleDownAnimation.setDuration(SCALE_DOWN_DURATION);
mCircleView.setAnimationListener(listener);
mCircleView.clearAnimation();
mCircleView.startAnimation(mScaleDownAnimation);
}
}
箭头随着下拉的距离透明度的改变
SwipeRefreshLayout.java
{
private static final int STARTING_PROGRESS_ALPHA = (int) (.3f * MAX_ALPHA);
@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_MOVE: {
mProgress.showArrow(true);
}
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_MOVE:
mProgress.setAlpha(STARTING_PROGRESS_ALPHA);
break;
}
}
}
ListView
RecyclerView
Bitmap
public final class Bitmap implements Parcelable {
}
Bitmap与Matrix
高效显示Bitmap
https://developer.android.com/topic/performance/graphics/index.html