仿美团外卖效果
来源:互联网 发布:mysql存放byteImage 编辑:程序博客网 时间:2024/06/03 02:40
下面ListView向上滚动时,先让上面的图片往上滚动,直到图片看不到时再让下面的ListView向上滚动。
当向下滑动时,先让ListView往下滑动,直到ListView不能往下滑动时在让上面图片往下滚动。
实现效果如下:
布局示意图
布局代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.meituanview.MainActivity" > <LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:layout_height="150dp" android:scaleType="centerCrop" android:src="@drawable/bag" /> <LinearLayout android:id="@+id/butsContainer" android:layout_width="match_parent" android:layout_height="@dimen/buts_container_height" android:background="#e1e1e1" android:orientation="horizontal" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:text="点菜" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:text="评价" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:text="商家" /> </LinearLayout> <com.example.meituanview.FloatListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="400dp" > </com.example.meituanview.FloatListView> </LinearLayout></RelativeLayout>
package com.example.meituanview;import android.annotation.SuppressLint;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.ListView;import android.widget.ScrollView;public class FloatListView extends ListView {public FloatListView(Context context) {super(context);init();}public FloatListView(Context context, AttributeSet attrs) {super(context, attrs);init();}public FloatListView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}@SuppressLint("NewApi")public FloatListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);init();}private void init() {}private int lastY;private int canScrollDistance; //可以滚动的最大距离,此处规定为布局中的ImageView的高度,可以根据需要修改 @Overridepublic boolean onTouchEvent(MotionEvent ev) {if (ev.getAction()==MotionEvent.ACTION_DOWN) {lastY=(int) ev.getRawY();canScrollDistance=((ViewGroup)getParent()).getChildAt(0).getHeight();System.out.println(canScrollDistance);return super.onTouchEvent(ev);}int currentY=(int) ev.getRawY();//一定要使用int型,否则误差会累积,导致慢慢往上滚动,当ImageView刚看不到时,ListView会突然上滚一段距离if (currentY<lastY) {View view=((ViewGroup)getParent());if (view.getScrollY()<canScrollDistance) {view.scrollBy(0, (int) (lastY-currentY));if (view.getScrollY()>canScrollDistance) {//防止迅速滑动时,界面滚动距离过大view.scrollTo(0, canScrollDistance);}lastY=currentY; return true;}}else if (getFirstVisiblePosition()==0&&getChildAt(0).getTop()==0 ) {View view=((ViewGroup)getParent());if (view.getScrollY()>0) {view.scrollBy(0, (int) (lastY-currentY));lastY=currentY;if (view.getScrollY()<0) {//防止迅速滑动时,界面滚动距离过大view.scrollTo(0, 0);}return true;}} lastY=(int) ev.getRawY();return super.onTouchEvent(ev);// 调用super.onTouchEvent会导致ListView滚动} }
public class MainActivity extends Activity {FloatListView floatListView;LinearLayout container;ViewGroup butsContainer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);floatListView=(FloatListView) findViewById(R.id.listview);container=(LinearLayout) findViewById(R.id.container); butsContainer=(ViewGroup) findViewById(R.id.butsContainer);WindowManager wm = this.getWindowManager(); int height = wm.getDefaultDisplay().getHeight(); int butsContainerHeight=(int) getResources().getDimension(R.dimen.buts_container_height); LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, height-butsContainerHeight-getStatusBarHeight());floatListView.setLayoutParams(params);floatListView.setAdapter(new MyAdapter());}protected int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; } class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {return 30;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {System.out.println(position+" "+convertView);if (convertView==null) {ViewGroup v=(ViewGroup) LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, floatListView,false);((TextView)v.getChildAt(1)).setText("null.."+position);return v;}ViewGroup v=(ViewGroup)convertView;((TextView)v.getChildAt(1)).setText(""+position);return convertView;}}}
dimens.xml
<dimen name="buts_container_height">50dp</dimen>
实现原理:
首先让最外面的LinearLayout包裹子控件,然后要设置FloatListView的高度,目的是让最外面的LinearLayout的高度大于屏幕的高度,这样调用最外面的LinearLayout的scrollBy方法时才能让布局正确滚动。
FloatListView中重写 public boolean onTouchEvent(MotionEvent ev) ,在这个方法内部根据手指滑动方向以及最外面的父控件滚动的距离和FloatListView中第一个可见item的位置来确定到底是最外面父控件滚动还是FloatListView滚动,若是最外面的父控件需要滚动,则手动调用最外面父控件的scrollBy 方法让父控件滚动,否则直接调用super.onTouchEvent(ev);则可以让FloatListView滚动。
原理介绍完了,但要实现上面截图中的效果需要借助StickyListHeaders https://github.com/emilsjolander/StickyListHeaders 这个控件
我们只需要让这个类库中的WrapperViewList继承自我们的FloatListView,并在StickyListHeadersListView中添加 这个方法
public FloatListView getFloatListView(){ return mList; }然后这样调用
se.emilsjolander.stickylistheaders.StickyListHeadersListView listview=new StickyListHeadersListView(getContext());listview.setAdapter(new TestBaseAdapter(getContext()));floatListView= listview.getFloatListView();floatListView.setScrollParent(scrollParent);floatListView.setScrollParentScrollDistance(distance);
下面附上两个工程的代码,一个是不需要依赖第三方类库 的FloatListView简单实现原理工程,另一个是集成了 .StickyListHeadersListView 的,并通过Fragment实现的工程
链接: http://pan.baidu.com/s/1i4hI6s1 密码: 5vmb
链接: http://pan.baidu.com/s/1i4jerop 密码: h9q8
- 仿美团外卖效果
- Android 仿美团外卖等下拉刷新效果
- 百度外卖-- 波浪效果实现
- 双ListView与顶部标题栏滑动事件处理(仿美团外卖商家详情界面滑动效果)
- 仿美团外卖源码加自己做了个模拟数据加载的效果
- 仿百度外卖个人界面动画效果
- 实现外卖选餐时两级tableView联动效果
- 实现外卖选餐时两级 tableView 联动效果
- 外卖
- android经典源码,仿美团外卖日历签到弹性指示器音乐播放器俄罗斯方块取色器飘落效果悬浮效果源码
- 浅谈百度外卖筛选悬浮框效果的实现
- 大众点评、百度外卖类滑动悬浮停止效果实现
- iOS 仿百度外卖-个人中心(头像波浪效果)
- iOS 仿百度外卖-个人中心(头像波浪效果)
- 仿Android端饿了么外卖的效果
- CoordinateLayout 自定义Behavior 仿百度外卖效果 实践
- CSS3高仿百度外卖头像波浪效果
- Android仿美团外卖点菜联动列表
- 音乐播放器单例
- LIS最长上升子序列模板
- Matlab里面的指针
- 轮播图封装
- Elasticsearch过滤与聚合的先后顺序java实现
- 仿美团外卖效果
- java类的生命周期分析
- 【quick-cocos2d-x】Lua 面向对象(OOP)编程与元表元方法
- HBase-6.hbase 协处理器
- 博客一周年and来深圳6年整
- 【三层架构】——C#代码分析
- Ubuntu 14.04 FTP服务器--vsftpd的安装和配置
- cocos2dx 网页版粒子编辑器
- Java 高级—— IO 基础