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

仿path首页滑动效果相关推荐

  1. IOS仿支付宝首页滑动效果

    项目来源翻译大神的swift 本版为objectc版本, 大神地址: 这里写链接内容 一.效果图如下: 没什么逻辑可讲述的,直接给源码吧: // // ViewController.m // ZFBH ...

  2. android+qq底部界面,Android 高仿QQ 界面滑动效果

    Android高仿QQ界面滑动效果 点击或者滑动切换画面,用ViewPager实现, 首先是布局文件: android:layout_width="match_parent" an ...

  3. 仿百度动态Android源码,Android 仿百度手机助手首页滑动效果

    今天看到百度手机助手首页上的滑动效果非常nice,主要功能归结为: 1.当手指上划时,顶部搜索栏随手指移动距离而缩小到隐藏,隐藏后内容还是可以继续移动 2.手指下滑时,当显示内容达到第一个时,顶部搜索 ...

  4. 仿菁优网首页动画效果

    原文链接 1.菁优网首页动画效果图 2.动画效果分析 2.1.动画效果一定是UIView动画,因为核心动画是CALayer的动画效果给我们的位移假象,视图的真实位置并没有发生变化.在首页的动画中,按钮 ...

  5. jQuery图片切换,轮播效果(仿迅雷首页FLASH效果)

    jQuery很不错的JS框架,现在已经更新到 1.2.6 了,添加了很多新特性,修正了大量的BUG. 今天,借助他的威力, 用js实现迅雷首页(http://xunlei.com/)FLASH轮换的效 ...

  6. 小程序仿安卓动画滑动效果滑动动画效果实现

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 效果图: 源码 var start_clientY; //记录当前滑动开始的值 var end_clientY ...

  7. 仿抖音滑动小短剧影视微信小程序源码带支付收益等模式

    项目功能介绍:支持无限滑动 高性能滑动 预加载 视频预览 支持剧情介绍,集合壁纸另外仿抖音滑动效果 支持会员模式,支持用户单独购买等等多功能 丰富的后台设置,具体大家可以看小编的后台演示图 具体小编也 ...

  8. Android 仿今日头条首页标题栏效果

    今天带来的是仿今日头条首页的联动滑动效果,废话不多说,先上效果图: 思路: 做这个我们需要实现的效果有 1.滑动内容区域,标题栏会有变化来显示当前所处的位置. 2.点击标题栏,内容区域也会随着滑动并跳 ...

  9. php 仿高德,仿高德路线规划滑动效果

    因为项目有个界面要模仿高德地图路径规划滑动效果,因此写了demo,并简单说下分析过程. 高德地图效果演示: 仿高德路线规划滑动.gif demo效果演示: 高德地图规划滑动.gif 一. 分析 首先, ...

最新文章

  1. Worktile荣获NextWorld 2020 年度优秀品牌奖
  2. 蓝桥杯 兰顿蚂蚁(模拟)
  3. 记录flink和spark提交任务常用句
  4. 微型计算机与裸机,第一章 微型计算机基础
  5. [Android Pro] 完美解决隐藏Listview和RecyclerView去掉滚动条和滑动到边界阴影的方案...
  6. Linux bunzip2命令:bz2格式的解压缩命令
  7. java 子类必须实现_Java学习之接口的子类必须实现接口的全部方法吗?
  8. linux性能评估-内存基础理解篇
  9. keil编译运行错误,缺少error:#5:#includecore_cm3.h_过路老熊_新浪博客
  10. mt4交易系统源码_mt4周边:一款免费的数据下载工具
  11. PAT (Basic Level) Practice1002 写出这个数
  12. 无法更新 TeamViewer 服务属性是什么意思?
  13. 干货 | 利用SPSS进行高级统计分析第四期
  14. Sketch 54.1 Shark 鲨鱼中文汉化特别版 Mac 设计师必备的原型UI设计工具
  15. 图片双面打印顺序混乱_打印,那些你没有注意的小细节
  16. ML之RL:强化学习Reinforcement Learning的简介、应用、经典案例、学习资源之详细攻略
  17. php滚动公告栏,jQuery实现上下滚动公告栏详细代码
  18. list.sort() 方法可以用函数作 key 的参数
  19. 百度的文心一言 ChatGTP 的对比
  20. 一款简单而强大的截图软件 Snipaste

热门文章

  1. 计算机专业马来西亚,去马来西亚读计算机专业如何
  2. java boolean 对象_为什么Java后端用Boolean属性筛选不出对象,但改成String类型就可以了?...
  3. 计算机动画专业哪个大学排名,哪些大学院校数字媒体艺术、动画专业比较排名...
  4. python123电脑登录不了_python(14)- 简单练习:登录账户失败三次,账户自动锁定...
  5. 剑指offer面试题[49]-把字符串转化为整型
  6. 基于jmeter测试web接口,看完都说学会了
  7. 从功能到接口,原来技能可以通用!
  8. mysql是否需要设置外键_数据库到底需不需要设置外键?
  9. 黑群晖 断电 检测有bad sector_金属你不会以为回收就能直接再用吧,不是的,这些再生金属材料检测知识,很少人知道...
  10. java 单元测试 异步_java - 如何使用CountdownLatch对异步代码进行单元测试同步 - 堆栈内存溢出...