您的位置:首页 > 其它

仿path首页滑动效果

2013-04-02 15:59 127 查看
最近在研究path的首页滑动效果,发现啪啪也已经实现了这个效果,自己网上找了代码,又自己试试,发现如果是用两个ImageView 做的话,可以实现,但是用listView的话,滑动就会出问题,现在把代码粘贴如下,望各位指点迷津:

主界面的xml:

<com.example.testpathscroll.MyScrollView xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/ll"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="vertical" >

<FrameLayout

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="vertical" >

<LinearLayout

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="vertical" >

<ImageView

android:id="@+id/iv1"

android:layout_width="fill_parent"

android:layout_height="200dip"

android:scaleType="center"

android:src="@drawable/bg" />

<ImageView

android:id="@+id/iv"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:src="@drawable/abcd" />

</LinearLayout>

<RelativeLayout

android:id="@+id/clock_rl"

android:layout_width="wrap_content"

android:layout_height="158dp" >

<include

android:id="@+id/clock"

android:layout_width="wrap_content"

android:layout_height="40dp"

android:layout_alignParentRight="true"

android:layout_marginTop="40dp"

layout="@layout/clock" />

</RelativeLayout>

</FrameLayout>

</com.example.testpathscroll.MyScrollView>

其中主要代码就是第一个Linear中的两个ImageView;

自定义的MyScrollView:

public class MyScrollView extends ScrollView {

public static interface OnPositionChangedListener {

public void onPositionChanged(int position);

public void onScollPositionChanged(View scrollBarPanel, int top);

}

private OnPositionChangedListener mPositionChangedListener;

static int k = 50;

ImageView iv1;

ImageView iv2;

int left, top;

// 记录初始的位置

int m_top;

float startX, startY;

float currentX, currentY;

int rootW, rootH;

private boolean isCount = false;// 是否开始计算

int iv1H;

int iv2H;

// 记录下面布局的上高度,就是上面图片的下边

int t;

Scroller scroller;

int myHeight, myHeight2;

int myWidth, myWidth2;

// View mClock;

Context mContext;

// 时间

// PopupWindow mPopUp;

// 判断显示还是隐藏

boolean flag = false;

ScrollView mScrollView;

RelativeLayout mRelativel;

int temp;

TranslateAnimation ta=null;

//尝试使用Scroller

Scroller mScroller;

/*sdfsdfsdf*/

private View inner1,inner2;// 孩子

private float y;// 坐标

private Rect normal2 = new Rect();// 矩形空白

private Rect normal1 = new Rect();// 矩形空白

public MyScrollView(Context context, AttributeSet attrs) {

super(context, attrs);

mContext = context;

// 第一张图片的高度,这个是需要(可以按照比例来制定,或者使用固定值,按照需要来)

Bitmap bm = BitmapCache.getInstance().getBitmap(R.drawable.bg, context);

myHeight = bm.getHeight();

myWidth = bm.getWidth();

// 第二张图片

Bitmap bm2 = BitmapCache.getInstance().getBitmap(R.drawable.abcd,

context);

myHeight2 = bm2.getHeight();

myWidth2 = bm2.getWidth();

temp=(int) (200*context.getResources().getDisplayMetrics().density);

//

mScroller=new Scroller(context);

// setFocusable(true);

// setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);

// setWillNotDraw(false);

}

public void setOnPositionChangedListener(

OnPositionChangedListener onPositionChangedListener) {

mPositionChangedListener = onPositionChangedListener;

}

// public void openTimeShow() {

// // set position

// mPopUp.showAtLocation(findViewById(R.id.ll), Gravity.CENTER, 0, 0);

// // mPopUp.showAsDropDown(view, 0, 0);

// }

// public void closeTimeShow(){

// mPopUp.dismiss();

// }

/**

* 所有子View被加载后触发

* */

protected void onFinishInflate() {

super.onFinishInflate();

iv1 = (ImageView) findViewById(R.id.iv1);

iv2 = (ImageView) findViewById(R.id.iv);

// mClock=(View) findViewById(R.id.clock);

mScrollView = (ScrollView) findViewById(R.id.ll);

setLongClickable(true);

scroller = new Scroller(getContext(),

new AccelerateDecelerateInterpolator());

// View view=LayoutInflater.from(mContext).inflate(R.id.clock_rl, null);

// mPopUp=new PopupWindow(view, LayoutParams.WRAP_CONTENT,

// LayoutParams.WRAP_CONTENT);

// mPopUp.setFocusable(false);

// mPopUp.setOutsideTouchable(true);

mRelativel = (RelativeLayout) findViewById(R.id.clock_rl);

/*sdfsdf*/

inner1 = iv1;

inner2 = iv2;// 获取其孩子

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

// TODO Auto-generated method stub

super.onLayout(changed, l, t, r, b);

m_top = iv2.getTop();

// 两张图片(两个布局的高度)

iv1H = iv1.getHeight();

iv2H = iv2.getHeight();

Log.i("TAG", iv1H + "---" + iv2H + "---" + m_top);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

int action = event.getAction();

currentX = event.getX();

currentY = event.getY();

switch (action & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_DOWN: {

if(ta!=null){

ta.cancel();

ta=null;

}

left = iv2.getLeft();

top = iv2.getTop();

rootW = getWidth();

rootH = getHeight();

// Log.i("TAG", "iv1H高度ACTION_DOWN---"+iv1H);

currentX = event.getX();

currentY = event.getY();

startX = currentX;

startY = currentY;

//Rect2

if (normal2.isEmpty()) {

// 填充矩形,目的:就是告诉this:我现在已经有了,你松开的时候记得要执行回归动画.

normal2.set(inner2.getLeft(), inner2.getTop(),

inner2.getRight(), inner2.getBottom());

}

//Rect1

if (normal1.isEmpty()) {

// 填充矩形,目的:就是告诉this:我现在已经有了,你松开的时候记得要执行回归动画.

normal1.set(inner1.getLeft(), inner1.getTop(),

inner1.getRight(), inner1.getBottom());

}

mPositionChangedListener.onScollPositionChanged(this,

getHeight() / 2);

break;

}

case MotionEvent.ACTION_MOVE:

Log.i("TAG", iv2.getY()+"!!!!!!!!!!!!!!!!!!");

int c_current = (int) currentY;

int l = (int) (left + currentX - startX);

int deltaY=(int) (currentY - startY);

if (!isCount) {

deltaY = 0; // 在这里要归0.

}

// 获取滑动距离

t = (int) (top + deltaY);

// Log.i("TAG", (currentY -

// startY)+"-----currentY - startY----!!!!"+currentY+"!!!!"+startY);

if (deltaY >= 0) {// 向下滑动

if (t > myHeight) {

t = myHeight;

}

// 控制时间条的位置

if (c_current > 854) {

c_current = 854;

}

} else {// 向上滑动

// 854 IS A TEST PX,the Height of screen

if (myHeight2 >= 854) {

if ((myHeight2 - 854) < -t) {

t = 854 - myHeight2;

}

} else {

if (myHeight2 - t < 800) {

t = 854 - myHeight2;

}

}

// 控制位置(800是屏幕的高度)

if (c_current < 0) {

c_current = 0;

}

}

mPositionChangedListener.onPositionChanged((int) currentY);

mPositionChangedListener.onScollPositionChanged(this,

(int) (startY - currentY));

// iv2.layout(left, t, left + iv2.getWidth(), t + iv2.getHeight());

inner2.layout(left, t, left + iv2.getWidth(), t + iv2.getHeight());

inner1.layout(0, 0, iv1.getWidth(), t);

isCount = true;

break;

case MotionEvent.ACTION_UP:

// closeTimeShow();

if (t <= temp) {// m_top

} else {

// System.out.println(temp+"------------"+t);

// animation(iv2, 0, 0, 0, temp - t);

// animation(iv1, 0, 0, 0, -temp/2);

if (isNeedAnimation()) {

animation();

isCount = false;

}

// 更新结束后,使用动画控制偏移过程, 3s内到位

// //mScroller.startScroll(0, 0, 0, temp,3000);

// // 重绘控件

// invalidate();

// iv2.layout(left, temp, left + iv2.getWidth(), temp + iv2.getHeight());

// iv1.layout(0, 0, iv1.getWidth(), temp);

}

break;

case MotionEvent.ACTION_CANCEL:

break;

case MotionEvent.ACTION_POINTER_DOWN:

break;

case MotionEvent.ACTION_POINTER_UP:

break;

}

return true;

}

/***

* 是否需要开启动画

*

* 如果矩形不为空,返回true,否则返回false.

*

*

* @return

*/

public boolean isNeedAnimation() {

return !normal2.isEmpty()&&!normal1.isEmpty();

}

/***

* 开启动画移动

*/

public void animation() {

// 开启移动动画

System.out.println(inner2.getTop()+"----inner2.getTop()----"+normal2.top+"---normal.top-----");

TranslateAnimation ta = new TranslateAnimation(0, 0, inner2.getTop()-normal2.top,

0);

ta.setDuration(300);

// TranslateAnimation ta1=new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 1f, Animation.RELATIVE_TO_PARENT, 1f, Animation.RELATIVE_TO_PARENT, 1f, Animation.RELATIVE_TO_PARENT, 0.5f);

// ta1.setDuration(500);

// ScaleAnimation sa=new ScaleAnimation(1.0f, 1.0f, 1.5f, 1.0f,

// Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f);

// sa.setDuration(300);

MyAnimation ma=new MyAnimation();

inner2.startAnimation(ta);

inner1.startAnimation(ma);

// 设置回到正常的布局位置

inner2.layout(normal2.left, normal2.top, normal2.right, normal2.bottom);

inner1.layout(normal1.left, normal1.top, normal1.right, normal1.bottom);

// 清空矩形

normal1.setEmpty();

normal2.setEmpty();

}

@Override

public void computeScroll() {

if (mScroller.computeScrollOffset()) { // 如果返回true,表示动画还没有结束

// 产生平滑的动画效果,根据当前偏移量,每次滚动一点

scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

// 此时同样也需要刷新View ,否则效果可能有误差

postInvalidate();

} else { //如果返回false,表示startScroll完成

}

}

public void animation(View view, float fromx, float tox, float fromY,

float toy) {

// 开启移动动画

ta = new TranslateAnimation(0, 0, fromY, toy);

ta.setInterpolator(new AccelerateDecelerateInterpolator());

ta.setDuration(500);

ta.setFillAfter(true);

// if(view.getId()==iv2.getId()){

ta.setAnimationListener(new AnimationListener() {

@Override

public void onAnimationStart(Animation animation) {

}

@Override

public void onAnimationRepeat(Animation animation) {

}

@Override

public void onAnimationEnd(Animation animation) {

//返回初始位置

iv2.layout(left, temp, left + iv2.getWidth(), temp + iv2.getHeight());

iv1.layout(0, 0, iv1.getWidth(), temp);

// view.clearAnimation();

// postInvalidate();

// Log.i("TAG", "iv1.getY() + iv2.getY()"+iv1.getY()+"----" + iv2.getY()+"---"+temp);

}

});

// }

view.startAnimation(ta);

// 设置回到正常的布局位置

}

}

这段代码就是处理下拉,反弹效果的。

主界面java文件:

public class MainActivity extends Activity implements OnPositionChangedListener{// implements OnTouchListener, OnPositionChangedListener

MyScrollView ll;

FrameLayout clockLayout;

private ExtendedListView dataListView;

private boolean areButtonsShowing;

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ll = (MyScrollView) findViewById(R.id.ll);

clockLayout = (FrameLayout)findViewById(R.id.clock);

ll.setOnPositionChangedListener(this);

}

private float[] computMinAndHour(int currentMinute, int currentHour) {

float minuteRadian = 6f * currentMinute;

float hourRadian = 360f / 12f * currentHour;

float[] rtn = new float[2];

rtn[0] = minuteRadian;

rtn[1] = hourRadian;

return rtn;

}

private float[] lastTime = {

0f, 0f

};

private RotateAnimation[] computeAni(int min, int hour) {

RotateAnimation[] rtnAni = new RotateAnimation[2];

float[] timef = computMinAndHour(min, hour);

// AnimationSet as = new AnimationSet(true);

// 创建RotateAnimation对象

// 0--图片从哪开始旋转

// 360--图片旋转多少度

// Animation.RELATIVE_TO_PARENT, 0f,// 定义图片旋转X轴的类型和坐标

// Animation.RELATIVE_TO_PARENT, 0f);// 定义图片旋转Y轴的类型和坐标

RotateAnimation ra = new RotateAnimation(lastTime[0], timef[0], Animation.RELATIVE_TO_SELF, 0.5f,

Animation.RELATIVE_TO_SELF, 0.5f);

ra.setFillAfter(true);

ra.setFillBefore(true);

// 设置动画的执行时间

ra.setDuration(800);

// 将RotateAnimation对象添加到AnimationSet

// as.addAnimation(ra);

// 将动画使用到ImageView

rtnAni[0] = ra;

lastTime[0] = timef[0];

// AnimationSet as2 = new AnimationSet(true);

// 创建RotateAnimation对象

// 0--图片从哪开始旋转

// 360--图片旋转多少度

// Animation.RELATIVE_TO_PARENT, 0f,// 定义图片旋转X轴的类型和坐标

// Animation.RELATIVE_TO_PARENT, 0f);// 定义图片旋转Y轴的类型和坐标

RotateAnimation ra2 = new RotateAnimation(lastTime[1], timef[1], Animation.RELATIVE_TO_SELF, 0.5f,

Animation.RELATIVE_TO_SELF, 0.5f);

// 设置动画的执行时间

ra2.setFillAfter(true);

ra2.setFillBefore(true);

ra2.setDuration(800);

// 将RotateAnimation对象添加到AnimationSet

// as2.addAnimation(ra2);

// 将动画使用到ImageView

rtnAni[1] = ra2;

lastTime[1] = timef[1];

return rtnAni;

}

@Override

public void onPositionChanged(int position) {

TextView datestr = ((TextView) findViewById(R.id.clock_digital_date));

datestr.setText("上午");

int hour = Calendar.getInstance().getTime().getHours()+position;

String tmpstr = "";

if (hour > 12) {

hour = hour - 12;

datestr.setText("下午");

tmpstr += " ";

} else if (0 < hour && hour < 10) {

tmpstr += " ";

}

tmpstr += hour + ":" + Calendar.getInstance().getTime().getMinutes();

((TextView) findViewById(R.id.clock_digital_time)).setText(tmpstr);

RotateAnimation[] tmp = computeAni(Calendar.getInstance().getTime().getMinutes(),hour);

ImageView minView = (ImageView) findViewById(R.id.clock_face_minute);

minView.startAnimation(tmp[0]);

ImageView hourView = (ImageView) findViewById(R.id.clock_face_hour);

hourView.setImageResource(R.drawable.clock_hour_rotatable);

hourView.startAnimation(tmp[1]);

}

@Override

public void onScollPositionChanged(View scrollBarPanel, int top) {

MarginLayoutParams layoutParams = (MarginLayoutParams)clockLayout.getLayoutParams();

layoutParams.setMargins(0, top, 0, 0);

clockLayout.setLayoutParams(layoutParams);

}

}

上面的效果经过测试还可以达到要求。但是实际项目中用到的可能是listview,而不是ImageView,这就会产生点击事件传递的问题。

希望有经验的大侠给点指点~小弟不胜感激!

文件下载地址:http://download.csdn.net/detail/ansionnal/5213545
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: