首页 > 其他分享 >缓存式的ViewPager&和其他手势控件冲突的解决办法

缓存式的ViewPager&和其他手势控件冲突的解决办法

时间:2023-04-06 22:44:27浏览次数:43  
标签:控件 缓存 container ViewPager Override position View public view


一般来说ViewPager如果有很多页的话,会加载它的上一页,当前页和下一页,当从n页以后再想回到第一页,就会再加载一次,这样第一页很多操作后的数据就会被重置,原因是在PagerAdapter的destroyItem经常会移除View,类似下面这样的代码:

@Override
        public void destroyItem(View container, int position, Object object)
        {
            // ((ViewPager) container).removeView(viewMap.get(position));//

        }




现在我不想移除它,需要让View保持原来的状态


那么就要采用一个Map用于保存View


HashMap<Integer, View> viewMap = new HashMap<Integer, View>();



然后在PagerAdapter的instantiateItem方法中如下用法:


@Override
        public Object instantiateItem(View container, int position)
        {
            View view = null;
            if (viewMap.containsKey(position))
            {
                view = viewMap.get(position);
            }
            else
            {
                view = getLayoutInflater().inflate(R.layout.item_for_gallery, null);
                viewMap.put(position, view);

                ((ViewPager) container).addView(view, 0);
}
}



这样就保证不会View不会被重置了。



伪代码如下:


package com.mobovip.bgr;

import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.view.ViewGroup;

import com.mobovip.model.Prize;
import com.mobovip.util.Utils;

public class PrizeActivity extends BaseActivity
{

    private Context context;

    private HashMap<Integer, View> viewMap = new HashMap<Integer, View>();

    private com.mobovip.view.MyViewPager viewPager;

    private MyAdapter adapter;

    private ArrayList<Prize> prizes;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_prize);
        context = this;
        initViews();
    }

    @Override
    public void onResume()
    {
        super.onResume();
        initValues();
    }

    @Override
    protected void onDestroy()
    {
        // TODO Auto-generated method stub
        super.onDestroy();
    }

    @Override
    protected void initViews()
    {
        // TODO Auto-generated method stub
        viewPager = (com.mobovip.view.MyViewPager) findViewById(R.id.viewPager);
        // viewPager.setOnPageChangeListener(new MyOnPageChangeListener());
    }

    @Override
    protected void initValues()
    {
        // TODO Auto-generated method stub

    }

    @Override
    protected void updateViews(Object obj)
    {
        // TODO Auto-generated method stub
        prizes = (ArrayList<Prize>) obj;
        if (prizes == null)
        {
            return;
        }

        if (adapter == null)
        {
            adapter = new MyAdapter();
            viewPager.setAdapter(adapter);
            viewPager.setCurrentItem(0);
        }
        else
        {
            adapter.notifyDataSetChanged();
        }

    }

    class MyAdapter extends PagerAdapter
    {

        @Override
        public void destroyItem(View container, int position, Object object)
        {
            // 无需removeView
            // ((ViewPager) container).removeView(viewMap.get(position));//
            // View view = (View)object;

        }

        @Override
        public void finishUpdate(View container)
        {
        }

        @Override
        public int getCount()
        {
            return prizes.size();
        }

        /**
         * 跳转到每个页面都要执行的方法
         */
        @Override
        public void setPrimaryItem(View container, int position, Object object)
        {
        }

        @Override
        public Object instantiateItem(View container, int position)
        {
            View view = null;
            if (viewMap.containsKey(position))
            {
                view = viewMap.get(position);
            }
            else
            {
                view = getLayoutInflater().inflate(R.layout.item_for_gallery, null);
                viewMap.put(position, view);
                final Prize prize = prizes.get(position);
                String format = "MM-dd-yyyy HH:mm:ss";
                int days = Utils.days(prize.getCreateTime(), getCurTime(format), format);
                prize.setExpires(prize.getExpires() - days);

                ((ViewPager) container).addView(view, 0);
                com.mobovip.view.WinView winView = (com.mobovip.view.WinView) view.findViewById(R.id.winView);
                winView.setPrize(prize);
                //处理其他逻辑
                ......
            }
            return view;
        }

        @Override
        public boolean isViewFromObject(View container, Object object)
        {
            return container == (object);
        }

        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1)
        {
        }

        @Override
        public Parcelable saveState()
        {
            return null;
        }

        @Override
        public void startUpdate(View container)
        {
        }

        @Override
        public void finishUpdate(ViewGroup container)
        {
            // TODO Auto-generated method stub
            super.finishUpdate(container);
        }

    }

}




上面有一个自定义控件WinView,是一个刮刮卡效果的类,上面有手势刮奖的效果,


现在问题是,由于ViewPager和WinView都具有手势操作的能力,所以这两个控件放在一起回发生冲突,为了防止这种冲突就需要重写一下ViewPager


import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

public class MyViewPager extends ViewPager
{
    public MyViewPager(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyViewPager(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y)
    {
        if (v != this && v instanceof WinView)
        {// 解决冲突
            return true;
        }
        return super.canScroll(v, checkV, dx, x, y);
    }

}




重写canScroll方法,将WinView排除在外即可。




如果不重写ViewPager,那么需要在WinView的


public boolean onTouchEvent(MotionEvent event)中写入如下语句,该方法专门用于剥夺父级控件的控制权



// 阻止父控件获得触摸操作,拦截触摸事件,防止与ViewPager等控件发生手势冲突
getParent().requestDisallowInterceptTouchEvent(true);




这样可以不用重写ViewPager了,推荐这样写(虽然我没试过!P)


标签:控件,缓存,container,ViewPager,Override,position,View,public,view
From: https://blog.51cto.com/u_5454003/6174202

相关文章

  • 高效快捷解决一个TextView显示多种字体的控件SpannableTextView
    这个控件本人强烈推荐,它会使得布局非常的简单且高效;下面这个布局如果是你,你会用多少层?多少控件生成?告诉你吧,一个SpannableTextView控件就搞定了!它把TextView和Spannable封装在了一起,可以在一个TextView中显示不同的字体颜色,大小,背景色等;它支持如下样式:*......
  • StepsView显示步骤执行情况的控件
    显示步骤执行情况的控件,在某些情况下,还是非常有用的。<com.anton46.stepsview.StepsViewxmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/stepsView0"android:layout_width="match_parent"......
  • .net webapi 客户端缓存 服务端缓存
    客户端缓存-ResponseCacheAttribute通过设置HTTP的响应头Cache-Control来完成页面存储到浏览器缓存中,如果请求在缓存有效期间就直接从浏览器缓存中取出数据。只需要在接口上方添加ResponseCacheAttribute特性即可设置客户端缓存。ResponseCacheAttribute可应用于:Razor......
  • Spring Cache使用方式——不用默认,使用redis进行缓存
    在SpringBoot项目中使用SpringCache的操作步骤(使用redis缓存技术)1、导入Maven坐标spring-boot-starter-data-redis、sping-boot-starter-cache2、配置application.ymlspring:cache:redis:time-to-live:1800000#设置缓存......
  • WPF的控件字符串内容使用StringFormat进行字符串转换
    在WPF中TextBlock的Text有时内容只需要改变个别数字,而不需要所以内容都修改,这时候就要使用StringFormat, 如:<TextBlockText="Ihavexxxfriends"/>这里面的xxx是个变量,那在Binding时应该怎样写呢<TextBlockText="{BindingFirendNumber,StringFormat='Ihave{0}firends......
  • LabVIEW调用第三方exe软件或操作操作控制第三方软件界面的控件,如操控烧录软件等
    LabVIEW调用第三方exe软件或操作操作控制第三方软件界面的控件,如操控烧录软件等除了模拟鼠标和键盘来实现之后,还可以考虑另外一种方式,使用窗口句柄来直接操作程序如下面图片实例,操作串口助手,修改串口和波特率,并写入数据和读取数据这种方式可以避免电脑的分辨率变化和位置移动等......
  • winCE 控件篇
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //页面测试伪数据privatevoidbindNumber(){#region页面数......
  • memcachaed内存缓存优化
    ①使用场景分类展示(当然只要是短期内不频繁更换的都可以用。。。只要你内存够)②安装方法推荐网址:http://www.lai18.com/content/627794.html③操作方法$mencache=newMemcache();$host='xx.x.xxx.xx'; $port='11211';  //默认端口设置:$memcache->set('class_name','tes......
  • 缓存菜品数据
    实现思路:前面已经实现了移动端菜品查看功能,对应的服务端方法为DishController中的list方法,此方法会根据前端提交的查询条件进行数据库查询操作。在高并发的情况下,频繁查询数据库会导致系统性能下降,服务端响应时间增长。现在需要对此方法进行缓存优化,提高系统的性能具体的实......
  • C++ MFC中嵌入web网页控件(WebBrowser、WebView2、CEF3)
    1、简介WebBrowser控件最常见的用途之一是向应用程序添加Internet浏览功能。使用IWebBrowser2接口,可以浏览到本地文件系统、网络或万维网上的任何位置。可以使用IWebBrowser2::Navigate方法告知控件要浏览到哪个位置。第一个参数是包含位置名称的字符串。要浏览到本地文件系......