最近项目要实现ScrollView中嵌套广告轮播图+RecyleView卡片布局,并且RecyleView按照header和内容的排列样式,因为RecyleView的可扩展性很强,所以我毫无疑问的选择了它,而且让RecyleView实现了可拖拽的效果,

最后我再加上了下拉刷新的效果(这里我用的下拉刷新控件是三方的SmartRefreshLayout)。记得刚开始实现这个效果的时候还是十分的得心印手。可是当我测试的时候,发现RecyleView的子item的拖拽效果并不流畅,起初我以

为是由于RecyleView和ScrollView的滑动冲突导致的,可是慢慢我自己重新写了个demo,逐步调试,发现肯定是下拉刷新控件和ScrollView的原因造成的,于是对症下药,终于找到了解决的办法,这里将我的答案记录下来,为了

后面其他的人遇到和我一样的问题,避免他们走很多的弯路,希望会对他们有所帮助,当然把自己遇到问题和解决问题的办法都记录下来,这对自己来说也是一种成长。如果有其他更好的思路,希望给我留言,谢谢。

 解决办法一:

        在布局页面中把ScrollView控件换成NestedScrollView控件:

        对NestedScrollView的详解:http://www.cnblogs.com/skytwo/p/4613912.html

    
  <android.support.v4.widget.NestedScrollView
     android:layout_width="match_parent"
     android:layout_height="match_parent">       .............. </android.support.v4.widget.NestedScrollView>
以下是简单demo:  


MainActivity:用底部BottomNavigationBar,实现viewpager和fragment连用
代码:
public class MainActivity extends AppCompatActivity implements BottomNavigationBar.OnTabSelectedListener,ViewPager.OnPageChangeListener{
private ViewPager viewPager;
private BottomNavigationBar bottomNavigationBar; //存放fragment的集合
private Fragment[] fragments; //切换不同fragment用的下标
private int index;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initBottomNavigationBar();
initViewPager(); }
//初始化底部导航菜单
private void initBottomNavigationBar() {
bottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);
bottomNavigationBar.setTabSelectedListener(this);
bottomNavigationBar.clearAll();
bottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);
bottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC);
bottomNavigationBar.addItem(new BottomNavigationItem(R.drawable.ic_launcher,"主页").setInactiveIconResource(R.drawable.ic_launcher).setActiveColorResource(R.color.colorPrimaryDark))
.addItem(new BottomNavigationItem(R.drawable.ic_launcher,"单据").setInactiveIconResource(R.drawable.ic_launcher).setActiveColorResource(R.color.colorPrimaryDark))
.addItem(new BottomNavigationItem(R.drawable.ic_launcher, "审核").setInactiveIconResource(R.drawable.ic_launcher).setActiveColorResource(R.color.colorPrimaryDark))
.addItem(new BottomNavigationItem(R.drawable.ic_launcher, "报表").setInactiveIconResource(R.drawable.ic_launcher).setActiveColorResource(R.color.colorPrimaryDark))
.addItem(new BottomNavigationItem(R.drawable.ic_launcher,"设置").setInactiveIconResource(R.drawable.ic_launcher).setActiveColorResource(R.color.colorPrimaryDark))
.initialise();
}
//初始化viewpager
private void initViewPager() {
viewPager = (ViewPager) findViewById(R.id.view_pager);
fragments = new Fragment[];
fragments[]=new FragOne();
fragments[]=new FragTwo();
fragments[]=new FragThree();
fragments[]=new FragFour();
fragments[]=new FragFive(); viewPager.setOffscreenPageLimit();
viewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager(), fragments));
viewPager.addOnPageChangeListener(this);
viewPager.setCurrentItem(); }
@Override
public void onTabSelected(int position) {
viewPager.setCurrentItem(position);
} @Override
public void onTabUnselected(int position) { } @Override
public void onTabReselected(int position) { } @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override
public void onPageSelected(int i) {
bottomNavigationBar.selectTab(i);
this.index = i; } @Override
public void onPageScrollStateChanged(int state) { } class SectionsPagerAdapter extends FragmentPagerAdapter {
Fragment fragments[]=new Fragment[]; public SectionsPagerAdapter(FragmentManager fm, Fragment fragments[]) {
super(fm);
this.fragments = fragments;
} @Override
public Fragment getItem(int position) {
return fragments[position];
} @Override
public int getCount() {
return fragments.length;
}
}
}
MainActity布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.admin.demo.MainActivity"> <android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=""
/>
<com.ashokvarma.bottomnavigation.BottomNavigationBar
android:id="@+id/bottom_navigation_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
/> </LinearLayout>
主fragment:实现下拉刷新、上拉加载、RecyleView拖拽等各种效果的fragment
public class FragOne extends Fragment implements MyItemTouchCallback.OnDragListener {
private List<String> list = new ArrayList<String>();
private View parent;
//显示模块的recyleview
private RecyclerView mRecyclerView;
//可拖动模块的帮助类
private ItemTouchHelper itemTouchHelper;
//适配器
private RecyleViewAdapter mRecyclerAdapter; //声明刷新控件
private SmartRefreshLayout srf; @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
parent = inflater.inflate(R.layout.frag_one, container, false);
initView();
return parent;
}
private void initView() {
for (int i = ; i < ; i++) {
list.add(i + "");
}
mRecyclerView = (RecyclerView) parent.findViewById(recyclerView); // 设置添加删除item的时候的动画效果
mRecyclerView.setItemAnimator(new DefaultItemAnimator()); GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), );
gridLayoutManager.setSmoothScrollbarEnabled(true);
gridLayoutManager.setAutoMeasureEnabled(true); mRecyclerView.setLayoutManager(gridLayoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setNestedScrollingEnabled(false); // 设置适配器
mRecyclerAdapter = new RecyleViewAdapter(list);
itemTouchHelper = new ItemTouchHelper(new MyItemTouchCallback(mRecyclerAdapter).setOnDragListener(this));
itemTouchHelper.attachToRecyclerView(mRecyclerView);
mRecyclerView.setAdapter(mRecyclerAdapter);
mRecyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(mRecyclerView) {
@Override
public void onLongClick(RecyclerView.ViewHolder vh) {
itemTouchHelper.startDrag(vh);
VibratorUtil.Vibrate(getActivity(), ); //震动70ms
} @Override
public void onItemClick(RecyclerView.ViewHolder vh) {
super.onItemClick(vh);
}
});
srf = (SmartRefreshLayout) parent.findViewById(R.id.refresh);
srf.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() {
@Override
public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
return new ClassicsHeader(context);//指定为经典Header,默认是 贝塞尔雷达Header
}
});
srf.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(RefreshLayout refreshlayout) {
srf.postDelayed(new Runnable() {
@Override
public void run() {
mRecyclerAdapter.notifyDataSetChanged(); srf.finishRefresh();
Toast.makeText(getActivity(), "刷新成功", Toast.LENGTH_SHORT).show();
}
}, );
}
});
srf.setEnableLoadmore(false);//屏蔽掉上拉加载的效果 } @Override
public void onFinishDrag() { } class RecyleViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements MyItemTouchCallback.ItemTouchAdapter {
private List<String> mData; public RecyleViewAdapter(List<String> data) {
mData = data;
} @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new TestViewHolder(View.inflate(parent.getContext(), R.layout.item_test, null));
} @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
TestViewHolder tHolder = (TestViewHolder) holder;
tHolder.tv.setText(mData.get(position));
} @Override
public int getItemCount() {
return mData == null ? : mData.size();
} @Override
public void onMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(mData, i, i + );
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(mData, i, i - );
}
}
notifyItemMoved(fromPosition, toPosition);
} @Override
public void onSwiped(int position) {
mData.remove(position);
notifyItemRemoved(position); } private class TestViewHolder extends RecyclerView.ViewHolder {
TextView tv; public TestViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
} } }
主fragment布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"> <android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/test" /> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"> <android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</com.scwang.smartrefresh.layout.SmartRefreshLayout> </LinearLayout>
RecyleView实现可拖拽效果的帮助类:
MyItemTouchCallback :
public class MyItemTouchCallback extends ItemTouchHelper.Callback {

    private ItemTouchAdapter itemTouchAdapter;
public MyItemTouchCallback(ItemTouchAdapter itemTouchAdapter){
this.itemTouchAdapter = itemTouchAdapter;
} @Override
public boolean isLongPressDragEnabled() {
return false;
} @Override
public boolean isItemViewSwipeEnabled() {
return true;
} @Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
final int swipeFlags = ;
return makeMovementFlags(dragFlags, swipeFlags);
} else {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = ;
return makeMovementFlags(dragFlags, swipeFlags);
}
} @Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();//得到拖动ViewHolder的position
int toPosition = target.getAdapterPosition();//得到目标ViewHolder的position
itemTouchAdapter.onMove(fromPosition,toPosition);
return true;
} @Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
itemTouchAdapter.onSwiped(position); } @Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
//滑动时改变Item的透明度
final float alpha = - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
viewHolder.itemView.setAlpha(alpha);
viewHolder.itemView.setTranslationX(dX);
} else {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
} @Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (background == null && bkcolor == -) {
Drawable drawable = viewHolder.itemView.getBackground();
if (drawable == null) {
bkcolor = ;
} else {
background = drawable;
}
}
viewHolder.itemView.setBackgroundColor(Color.LTGRAY);
}
super.onSelectedChanged(viewHolder, actionState);
} @Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder); viewHolder.itemView.setAlpha(1.0f);
if (background != null) viewHolder.itemView.setBackgroundDrawable(background);
if (bkcolor != -) viewHolder.itemView.setBackgroundColor(bkcolor);
//viewHolder.itemView.setBackgroundColor(0); if (onDragListener!=null){
onDragListener.onFinishDrag();
}
} private Drawable background = null;
private int bkcolor = -; private OnDragListener onDragListener;
public MyItemTouchCallback setOnDragListener(OnDragListener onDragListener) {
this.onDragListener = onDragListener;
return this;
}
public interface OnDragListener{
void onFinishDrag();
} public interface ItemTouchAdapter {
void onMove(int fromPosition, int toPosition);
void onSwiped(int position);
}
}
OnRecyclerItemClickListener:
public class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener{
private GestureDetectorCompat mGestureDetector;
private RecyclerView recyclerView; public OnRecyclerItemClickListener(RecyclerView recyclerView){
this.recyclerView = recyclerView;
mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(),new ItemTouchHelperGestureListener());
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetector.onTouchEvent(e);
return false;
} @Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
mGestureDetector.onTouchEvent(e);
} @Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { }
private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener { @Override
public boolean onSingleTapUp(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child!=null) {
RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
onItemClick(vh);
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child!=null) {
RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
onLongClick(vh);
}
}
}
public void onLongClick(RecyclerView.ViewHolder vh){}
public void onItemClick(RecyclerView.ViewHolder vh){}
}
 VibratorUtil(手机振动工具类)
/**
* 手机震动工具类
* @author Administrator
* 使用必须添加权限:<uses-permission android:name="android.permission.VIBRATE" />
*/
public class VibratorUtil { /**
* final Activity activity :调用该方法的Activity实例
* long milliseconds :震动的时长,单位是毫秒
* long[] pattern :自定义震动模式 。数组中数字的含义依次是[静止时长,震动时长,静止时长,震动时长。。。]时长的单位是毫秒
* boolean isRepeat : 是否反复震动,如果是true,反复震动,如果是false,只震动一次
*/
public static void Vibrate(final Activity activity, long milliseconds) {
Vibrator vib = (Vibrator) activity.getSystemService(Service.VIBRATOR_SERVICE);
vib.vibrate(milliseconds);
}
public static void Vibrate(final Activity activity, long[] pattern, boolean isRepeat) {
Vibrator vib = (Vibrator) activity.getSystemService(Service.VIBRATOR_SERVICE);
vib.vibrate(pattern, isRepeat ? : -);
} }

Android 解决下拉刷新控件和ScrollVIew的滑动冲突问题。的更多相关文章

  1. Android解决下拉刷新控件SwipeRefreshLayout和ViewPager的滑动冲突

    直接说明下我自己项目中的情况,如图: 外部嵌套任何一种refresh下拉控件之后,上方的viewpager左右滑动事件都受到影响,滑动不流畅,稍微有点向下的趋势就会触发刷新. 起初以为可能跟不同下拉控 ...

  2. Android PullToRefresh下拉刷新控件的简单使用

    PullToRefresh这个开源库早就听说了,不过一直没用过.作为一个经典的的开源库,我觉得还是有必要认识一下. 打开github上的网址:https://github.com/chrisbanes ...

  3. android官方下拉刷新控件SwipeRefreshLayout的使用

    可能开发安卓的人大多数都用过很多下拉刷新的开源组件,但是今天用了官方v4支持包的SwipeRefreshLayout觉得效果也蛮不错的,特拿出来分享. 简介:SwipeRefreshLayout组件只 ...

  4. 【转】Android官方下拉刷新控件 SwipeRefreshLayout

    今天在Google+上看到了SwipeRefreshLayout这个名词,遂搜索了下,发现竟然是刚刚google更新sdk新增加的一个widget,于是赶紧抢先体验学习下. SwipeRefreshL ...

  5. 基于PtrFrameLayout实现自定义仿京东下拉刷新控件

    前言 最近基于项目需要,使用PtrFrameLayout框架实现了自定义的下拉刷新控件,大体效果类似于京东APP的下拉刷新动态效果.在这里和大家分享一下具体的思路和需要注意的地方,以便帮助有类似开发和 ...

  6. [Android]下拉刷新控件RefreshableView的实现

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4172483.html 需求:自定义一个ViewGroup,实现 ...

  7. android SwipeRefreshLayout google官方下拉刷新控件

    下拉刷新功能之前一直使用的是XlistView很方便我前面的博客有介绍 SwipeRefreshLayout是google官方推出的下拉刷新控件使用方法也比较简单 今天就来使用下SwipeRefres ...

  8. Android SwipeRefreshLayout 官方下拉刷新控件介绍

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24521483 下面App基本都有下拉刷新的功能,以前基本都使用XListView ...

  9. Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件

    前言: 忙完了结婚乐APP的开发,终于可以花一定的时间放在博客上了.好了,废话不多说,今天我们要带来的效果是苹果版本的QQ下拉刷新.首先看一下目标效果以及demo效果:      因为此效果实现的步骤 ...

随机推荐

  1. P1726 上白泽慧音(0分)

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

  2. es6总结(一) ——开发环境

    我们使用Babel把ES6编译成ES5 安装方法: a.先建立一个项目的工程目录,并在目录下边建立两个文件夹:src和dist src:书写ES6代码的文件夹,写的js程序都放在这里. dist:利用 ...

  3. getElementsByClassName 方法兼容性封装方法二

    var getElmsByClsName = function(className, results) { results = results || []; // 判断浏览器是否支持 getEleme ...

  4. SQL--left join ,inner join, right jion, Limit

    SQL Limit 语句 用于返回规定的数量记录.当数据库中的数据量十分庞大时,可以使用,返回指定的数量记录. 语句如:select * from grade limit 5.返回grade表中的前面 ...

  5. Android 蓝牙4.0的连接和通讯

    1.加入权限 <uses-sdk android:minSdkVersion=" android:targetSdkVersion="/> <uses-featu ...

  6. Android开发中:小米2S DDMS 不显示

    参考:http://bbs.xiaomi.cn/thread-5672159-1-1.html

  7. Linux内核分析笔记

    我在MOOC<Linux内核分析>的学习笔记,这里只做个索引! 计算机是如何工作的

  8. 【摘录】JAVA内存管理-自动选择垃圾收集器算法

    在J2SE 5.0,垃圾收集的默认值:垃圾收集器.堆大小以及JVM的类型(客户端还是服务器)都会根据应用运行的硬件平台和操作系统自动选择.相比之前设置命令行参数的方式,自动选择很好的匹配了不同类型的应 ...

  9. The German Collegiate Programming Contest 2017

    B - Building 给一个m各面的多边形柱体,每一侧面有n*n个格子,现在对这些格子染色,看有多少种方式使得多面柱体无论如何旋转都不会与另一个一样. #include <bits/stdc ...

  10. npm run eject 命令后出现This git repository has untracked files or uncommitted changes错误

    npm run eject 暴露隐藏的文件,不可逆 结果出现下面的问题 This git repository has untracked files or uncommitted changes: ...