为什么Viewpager instantiateItem()在android中加载两次?

时间:2016-01-18 11:17:41

标签: android

说明: 我正在动态创建Viewpager,它根据List的大小

这是我的activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.domore.viewpagerposition.MainActivity">

    <android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager_recent_matches"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="@android:color/transparent" />
</LinearLayout>

这是我的MainActivity.java

public class MainActivity extends AppCompatActivity {

    ViewPager pager;
    List<String> lst=null;
    LiveAdapter adapter=null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pager=(ViewPager)findViewById(R.id.pager_recent_matches);
        lst=new ArrayList<>();

        lst.add("notstarted");
        lst.add("started");
        lst.add("started");
        lst.add("notstarted");

        adapter=new LiveAdapter(this,lst);
        pager.setAdapter(adapter);
    }
}

这是我的Adapter类

public class LiveAdapter extends PagerAdapter {

    private Context context;
    private LayoutInflater inflater;
    private List<String> lst;
    String lst_value="";

    public LiveAdapter(Context context,List<String> lst){
        this.context=context;
        this.lst=lst;
        inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

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

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        final View itemView=inflater.inflate(R.layout.simple_layout,container,false);
        TextView txtname=(TextView)itemView.findViewById(R.id.txtname);

        itemView.setTag(position);
        lst_value=this.lst.get(position);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos=(int)itemView.getTag();

                if(pos==0){
                    if(lst_value.equals("notstarted")) {
                        Toast.makeText(context, "notstarted", Toast.LENGTH_SHORT).show();
                    }
                    if(lst_value.equals("started")){
                        Toast.makeText(context, "started", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });

        container.addView(itemView);
        return itemView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((LinearLayout)object);
    }
}

它在吐司信息上开始打印这就是问题所在。

我在运行应用程序时记录了值。

01-18 16:53:15.769 27799-27799/com.domore.viewpagerposition E/POSITION: 0
01-18 16:53:15.769 27799-27799/com.domore.viewpagerposition E/POSITION: 1

加载应用程序后,我试图直接滑动并定位返回2。

我的问题是为什么我同时有两个时间位置价值???? 当我刷卡然后我为什么得到2而不是1 ????

请帮我解决这个问题

2 个答案:

答案 0 :(得分:2)

这是因为ViewPager正在预加载页面以获得更流畅的动画效果。 要在当前值之外加载的默认页面设置为1。 这意味着在启动时它会加载默认值(0)和旁边的值(1)。当您滑动到第一页时,它必须预先加载它旁边的那个,位置为2。

您可以使用viewPager.setOffscreenPageLimit(number);

增加此值

最小值为1,这也是默认值。

如果您只想获取当前位置,请在ViewPager上使用监听器:

viewPager.setOnPageChangeListener(new OnPageChangeListener(){

  @Override
  public void onPageScrollStateChanged(int state) {
   // Called when the scroll state changes (scroll started - ended)
  }

  @Override
  public void onPageScrolled(int position, 
    float positionOffset, int positionOffsetPixels) {
   // This is called a lot of times when the user is scrolling
  }

  @Override
  public void onPageSelected(int position) {
      // Check position here to see which page was selected
  }
}); 

答案 1 :(得分:1)

根据@Daniel Zolnai的答案,他是绝对正确的。 在这里,我发现了一个完美的帖子解决方案。

将另一个列表从您的homefragment传递到适配器,如下所示:

List<String> list=new ArrayList<>();

//Now, add the elements to the newly created list

list.add("notstarted");
list.add("started");
list.add("started");
list.add("notstarted");

//Add into adapter constructor parameter
adapter=new LiveAdapter(this,lst,list);

这里是适配器的构造函数

public LiveAdapter(Context context,List<JSONObject> lst,int pagerLength,List<String> list_status){
        this.context=context;
        this.lst=lst;
        this.list_status=list_status;
        this.pagerLength=pagerLength;
        inflater=(LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

这是你的适配器代码onclick()方法

itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String status_value=list_status.get(position);
                if(status_value.equals("notstarted")){
                    Log.e("status",""+status_value);
                    Intent intent=new Intent(context,NotStartedMatchDetails.class);
                    context.startActivity(intent);
                }
            }
        });
不要忘记将你的位置参数设为instantiateItem()方法参数的 final