复习下。
主要用到了View的基本绘制测量和布局知识,以及Scroller的使用,还有就是VelocityTracker。
*主要控制滑动代码
package com.cc.MyScroller;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.Scroller;
/**
* Created by cc on 2016/9/23.
*/
public class InsideScrollView extends ViewGroup{
Scroller mScroller;
Adapter mAdapter;
VelocityTracker mVelocityTracker;
int mMaximumVelocity, mMinimumVelocity, mScaledTouchSlop;
public InsideScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
mVelocityTracker = VelocityTracker.obtain();
ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
mMaximumVelocity = viewConfiguration.getScaledMaximumFlingVelocity();
mMinimumVelocity = viewConfiguration.getScaledMinimumFlingVelocity();
mScaledTouchSlop = viewConfiguration.getScaledTouchSlop();
setFocusable(true);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(mScroller.computeScrollOffset()){
mScroller.forceFinished(true);
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
last = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int in = (int) (ev.getY() - last);
if(Math.abs(in) > mScaledTouchSlop){
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
View view = null;
int height = 0;
for(int i = 0 ; i < getChildCount() ; i ++){
view = getChildAt(i);
measureChild(view, widthMeasureSpec, heightMeasureSpec);
height += view.getMeasuredHeight();
}
setMeasuredDimension(view.getMeasuredWidth(), height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if(changed){
View view = null;
int top = 0;
for(int i = 0 ; i < getChildCount() ; i ++){
view = getChildAt(i);
view.layout(0, top, view.getMeasuredWidth(), top + view.getMeasuredHeight());
top += view.getMeasuredHeight();
}
}
}
int last = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
event = MotionEvent.obtain(event);
mVelocityTracker.addMovement(event);
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
last = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int length = (int) (event.getY() - last);
scrTo(0, getScrollY() - length);
last = (int) event.getY();
break;
case MotionEvent.ACTION_UP:
int x = getScrollX();
int y = getScrollY();
mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int initialVelocity = (int) mVelocityTracker.getYVelocity();
if(Math.abs(initialVelocity) > mMinimumVelocity){
mScroller.startScroll(0, y, 0, -initialVelocity/2, 1000);
invalidate();
}
mVelocityTracker.clear();
break;
}
return true;
}
@Override
public void computeScroll() {
if(mScroller.computeScrollOffset()){
int x = mScroller.getCurrX();
int y = mScroller.getCurrY();
Log.i("mScroller", x + ", " + y);
scrTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}
super.computeScroll();
}
/**
* 限制滑动的边界
* **/
public void scrTo(int x, int y){
ViewGroup viewGroup = (ViewGroup) getParent();
int viewGroupHeight = viewGroup.getHeight();
if(getHeight() <= viewGroupHeight){
return;
}
//禁止超出底部
if(viewGroupHeight + y > getHeight()){
y = getHeight() - viewGroupHeight;
}else
//禁止超出顶部
if(y < 0){
y = 0;
}
scrollTo(0, y);
}
public void setAdpter(Adapter adapter){
this.mAdapter = adapter;
for(int i = 0 ; i < adapter.getCount() ; i ++){
addView(adapter.getView(i, null, null));
}
}
}
package com.cc.MyScroller;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Adapter;
import android.widget.RelativeLayout;
/**
* Created by cc on 2016/9/24.
*/
public class MySrcollView extends RelativeLayout{
InsideScrollView mInsideScrollView;
public MySrcollView(Context context, AttributeSet attrs) {
super(context, attrs);
mInsideScrollView = new InsideScrollView(context, null);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
mInsideScrollView.setLayoutParams(lp);
addView(mInsideScrollView);
}
public void setAdpter(Adapter adapter){
mInsideScrollView.setAdpter(adapter);
}
}
package com.cc.MyScroller;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
/**
* Created by cc on 2016/9/23.
*/
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final MySrcollView viewGroup = (MySrcollView) findViewById(R.id.mainlayout);
viewGroup.setAdpter(new BaseAdapter() {
@Override
public int getCount() {
return 120;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Button button;
button = new Button(getApplicationContext());
button.setText(String.valueOf(position));
button.setLayoutParams(lp);
return button;
}
});
}
}
界面:
总的来说还算良好,滑动挺流畅的,当然,是在控件少的情况下,下次研究下listView