关闭

兼容viewpager中嵌套的viewpager自定义控件

标签: androidviewpager内存缓存java
559人阅读 评论(0) 收藏 举报
分类:

项目中viewpager市经常使用的控件。

一旦项目大起来之后经常使用viewpager中嵌套viewpager 。

那么使用时候有很多地方都会出现冲突。

这里模仿viewpager写了一个自定义viewpager 具有回收功能的viewpager 可以减轻内存消耗。

代码如下:

public class ViewPagerHorizontalScrollView extends HorizontalScrollView {

	Context context;
	PagerScrollAdapter pagerScrollAdapter;
	LinearLayout linearLayout;
	boolean isOnce = true;
	int mWitdh;
	private FrameLayout.LayoutParams layoutParams;
	int xDown;
	long startTime, endTime;
	int lastIndex;
	int cacheNums = 1;// save cache
	FrameLayout.LayoutParams layoutParams2;

	public ViewPagerHorizontalScrollView(Context context,
			PagerScrollAdapter pagerScrollAdapter) {
		super(context);
		this.context = context;
		this.pagerScrollAdapter = pagerScrollAdapter;
		setHorizontalScrollBarEnabled(false);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);

		if (changed && isOnce) {
			isOnce = false;
			
			mWitdh = getWidth();
			linearLayout= new LinearLayout(context);
			layoutParams=new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
			layoutParams2=new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
			linearLayout.setLayoutParams(layoutParams);
			linearLayout.setOrientation(LinearLayout.HORIZONTAL);
			linearLayout.setBackgroundColor(context.getResources().getColor(android.R.color.holo_red_light));
			removeAllViews();
			addView(linearLayout);
			if (pagerScrollAdapter.getCount()<=0) {
				return;
			}
			//add child 
			linearLayout.removeAllViews();
			for (int i = 0; i < pagerScrollAdapter.getCount(); i++) {
				LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(mWitdh, getHeight());
				FrameLayout frameLayout=new FrameLayout(context);
				frameLayout.setLayoutParams(layoutParams);
				linearLayout.addView(frameLayout);
			}
			RecylerAddView();
			
		}
	}
	
	void RecylerAddView(){
		//clear prev
		int preNum = lastIndex - cacheNums;
		if (preNum>0) {//need recyler
			for (int i = 0; i < preNum; i++) {
				int childNum = ((FrameLayout)linearLayout.getChildAt(i)).getChildCount();
				if (childNum>0) {
					((FrameLayout)linearLayout.getChildAt(i)).removeAllViews();
				}
			}
		}
		//clear next
		int nextNum = lastIndex + cacheNums;
		if (nextNum < pagerScrollAdapter.getCount() - 1) {
			for (int i = nextNum+1; i <= pagerScrollAdapter.getCount()-1; i++) {
				int childNum = ((FrameLayout)linearLayout.getChildAt(i)).getChildCount();
				if (childNum>0) {
					((FrameLayout)linearLayout.getChildAt(i)).removeAllViews();
				}
			}
		}
		//add viewView
		for (int i = preNum; i <= nextNum; i++) {
			if (i<0 || i > pagerScrollAdapter.getCount()-1) {
				continue;
			}
			int childNum = ((FrameLayout)linearLayout.getChildAt(i)).getChildCount();
			if (childNum==0) {
				//add view
				View view=pagerScrollAdapter.getView(i);
				view.setLayoutParams(layoutParams2);
				((FrameLayout)linearLayout.getChildAt(i)).addView(view);
			}
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		if (ev.getAction()==MotionEvent.ACTION_DOWN) {
			startTime = System.currentTimeMillis();
			xDown = (int)ev.getRawX();
		}
		if (ev.getAction()==MotionEvent.ACTION_UP || ev.getAction()==MotionEvent.ACTION_CANCEL) {
			StopScrollView(ev);
			return true;
		}
		return super.onTouchEvent(ev);
	}
	
	public void setCurrentView(int position){
		smoothScrollTo((position * mWitdh), 0);
		if (mListener!= null && lastIndex!=position) {
			setCurrentPage(position);
		}
	}
	
	void StopScrollView(MotionEvent ev){
		endTime = System.currentTimeMillis();
		int xUp = (int)ev.getRawX();
		int distance = Math.abs(xUp-xDown);
		int moveNums = xUp - xDown;
		int moveX = getScrollX();
		int leftorright = moveX%mWitdh;
		int nums = moveX/mWitdh;
		if ( (endTime-startTime)<470 && distance > 50 ) {
			if (moveNums<0) {
				// xiang left
				smoothScrollTo(((nums+1)*mWitdh), 0);
				if (mListener!= null && lastIndex!=(nums+1)) {
					setCurrentPage(nums+1);
				}
			}else {
				// xiang right
				smoothScrollTo((nums*mWitdh), 0);
				if (mListener!= null && lastIndex!=(nums)) {
					setCurrentPage(nums);
				}
			}
			return;
		}
		if (leftorright< mWitdh/2) {
			//left
			smoothScrollTo((nums*mWitdh), 0);
			if (mListener!= null && lastIndex!=(nums)) {
				setCurrentPage(nums);
			}
		}else {
			//right
			smoothScrollTo(((nums+1)*mWitdh), 0);
			if (mListener!= null && lastIndex!=(nums+1)) {
				setCurrentPage(nums+1);
			}
		}
	}
	
	void setCurrentPage(int index){
		mListener.currentPgae(index);
		lastIndex = index;
		RecylerAddView();
	}

	public interface PagerScrollAdapter {
		int getCount();
		View getView(int pos);
	}
	
	onPageChangeListener mListener;
	
	public void setPageListener(onPageChangeListener mChangeListener){
		this.mListener = mChangeListener;
	}
	
	public interface onPageChangeListener{
		void currentPgae(int index);
	}



}


使用代码:

        ViewPagerHorizontalScrollView view=new ViewPagerHorizontalScrollView(getApplicationContext(), new ViewPagerHorizontalScrollView.PagerScrollAdapter() {
			
			@Override
			public View getView(int pos) {
				//获取每个项目试图
				TextView textView=new TextView(getApplicationContext());
				textView.setText("编号"+pos);
				return textView;
			}
			
			@Override
			public int getCount() {
				// 获取数量
				return 10;
			}
		});
        //添加进入布局中 只支持代码添加
        //iblShopContentViewContent.addView(View);
        //view.setCurrentView(0);//选中每一个项目




0
0
查看评论

关于viewpager+fragment中嵌套viewpager+fragment的问题处理:

当在Fragment中再添加一个带有Fragment的控件时  程序第一次运行时 没错,当父Fragment(也就是最外面的Fragmnet)划动2个以上的时候,子Fragmnet就出现问题了: 1:子Fragment显示一片空白,原因何在呢?    最后在网上查找...
  • li530893850
  • li530893850
  • 2015-09-07 11:14
  • 1185

解决ViewPager中嵌套ViewPager的滑动分发问题

本文主要解决ViewPager中嵌套ViewPager的滑动分发问题,自定义ViewPager,即BannerViewPager。 阻止子ViewPager中滑动事件不再分发给父ViewPager滑动。
  • langxm2006
  • langxm2006
  • 2016-11-12 23:54
  • 585

ViewPager相互嵌套,里层ViewPager无法滑动

ViewPager嵌套ViewPager,默认情况下,里层的ViewPager,是无法滑动的!
  • gaojinshan
  • gaojinshan
  • 2014-01-07 10:19
  • 26656

ViewPager+Fragment以及Fragment嵌套ViewPager

最近新项目用到Fragment嵌套ViewPager的时候出现了一些问题,现在把之前遇到的问题总结一下。1.Fragment嵌套ViewPager时,加载两个Fragment,不显示内容。先是将Home_Live_Adapter adapter = new Home_Live_Adapter(get...
  • u012800816
  • u012800816
  • 2016-04-22 16:27
  • 481

Fragment中嵌套ViewPager,ViewPager中有多个Fragment,不显示

最近在项目中用到首页是一个Fragment,底部四个按钮切换,第二个按钮切换的时候是一个ViewPager嵌套Fragmet,但是遇到点击第二个按钮切换的时候,ViewPager不显示。才发现构造方法传入的FragmentManager有问题。//不显示 mViewPager.setAdapter(...
  • e_Inch_Photo
  • e_Inch_Photo
  • 2017-04-02 12:01
  • 536

ViewPager的用法(3)——ViewPager嵌套Fragment

1、ViewPager嵌套Fragment的重点 (1)Activity继承了V4包下的FragmentActivity (2)数据源中的List   变成了List          ...
  • u011809714
  • u011809714
  • 2016-03-14 16:22
  • 3030

Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment

前几天,项目中要实现这么一个功能。就配置了下。其实很简单,首先 需要阅读下我转载的前两篇文章,都是转载的郭神的,写的非常好。我的项目中逢者必用,其实就相当于一个很好的框架来使用,非常方便。 前两篇的项目地址Android Fragment应用实战,使用碎片向ActivityGroup说再见和Andr...
  • qq_24956515
  • qq_24956515
  • 2016-03-27 11:16
  • 7816

RecyclerView 中嵌套ViewPager不显示

一个多种布局的RecyclerView中,有的item是图片,有的是文字,竟然还有的要是ViewPager!  type可以通过getItemViewType来做,可ViewPager的setAdapter()没有显示  后来看了下文档,RecyclerView的it...
  • cxc19890214
  • cxc19890214
  • 2015-11-10 14:20
  • 3739

Android中ScrollView中嵌套ViewPager导致ViewPager不显示问题

首先看ScrollView中有没有加入fillViewport属性,同时ViewPager设置为固定高度,切记设置高度是个关键,否则会出现ViewPager充满屏幕的情况。         android:layout_width="match...
  • Toast_qi
  • Toast_qi
  • 2016-09-22 11:25
  • 805

viewPager和listview嵌套冲突

viewPager和listView嵌套使用时,viewPager是作为容器,父布局,而listView是写在viewPager中的,那么对于点击或者滑动事件发生时,会调用dispatchTouch来进行事件的传递,此时重写父控件的onInterceptTouchEvent函数,在move的时候根据...
  • u010424498
  • u010424498
  • 2016-01-20 20:03
  • 1226
    个人资料
    • 访问:100334次
    • 积分:2369
    • 等级:
    • 排名:第18587名
    • 原创:131篇
    • 转载:46篇
    • 译文:0篇
    • 评论:11条
    个人简介
    我的第一个app
    如果需要交流的话可以联系我
    验证消息:csdn
    扣扣: 1937306285
    文章分类
    最新评论