仿path首页滑动效果

来源:互联网 发布:推荐几个精仿的淘宝店 编辑:程序博客网 时间:2024/06/11 09:46

最近在研究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

原创粉丝点击