2016-02-24 105 views
0

试图使用addOnPageChangeListener从到的ViewPager是不同类的,我注意到,它会导致一个奇怪的行为...指令在第一时间拿到他们被称为后,执行多次。我做了一个非常自动生成的样本项目,所以你可以看到自己:奇怪的行为(错误?)

MainActivity.java:

package com.example.laptop.test; 

import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.os.Bundle; 
import android.view.View; 

public class MainActivity extends AppCompatActivity { 

    private SectionsPagerAdapter mSectionsPagerAdapter; 
    static ViewPager mViewPager; 

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

     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 

     mViewPager = (ViewPager) findViewById(R.id.container); 
     mViewPager.setAdapter(mSectionsPagerAdapter); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
         .setAction("Action", null).show(); 
      } 
     }); 

    } 

    public class SectionsPagerAdapter extends FragmentPagerAdapter { 

     public SectionsPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      switch (position){ 
       case 0: 
        return new TestActivity(); 
       case 1: 
        return new TestActivity2(); 
       case 2: 
        return new TestActivity2(); 
      } return null; 
     } 

     @Override 
     public int getCount() { 
      // Show 3 total pages. 
      return 3; 
     } 
    } 
} 

TestActivity.java:

package com.example.laptop.test; 

import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class TestActivity extends android.support.v4.app.Fragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_test, container, false); 
     return rootView; 
    } 
    } 

TestActivity2.java:

package com.example.laptop.test; 

import android.os.Bundle; 
import android.support.v4.view.ViewPager; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

public class TestActivity2 extends android.support.v4.app.Fragment { 

    int i=0; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     final View rootView = inflater.inflate(R.layout.fragment_test2, container, false); 

     MainActivity.mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
      @Override 
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 

      } 

      @Override 
      public void onPageSelected(int position) { 

       if(position==1){ 

        Toast.makeText(rootView.getContext(),i+"",Toast.LENGTH_SHORT).show(); 
        i++; 
       } 

      } 

      @Override 
      public void onPageScrollStateChanged(int state) { 

      } 
     }); 

     return rootView; 
    } 
    } 

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 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:id="@+id/main_content" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true" 
    tools:context="com.example.laptop.test.MainActivity"> 

    <android.support.design.widget.AppBarLayout 
     android:id="@+id/appbar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:paddingTop="@dimen/appbar_padding_top" 
     android:theme="@style/AppTheme.AppBarOverlay"> 

     <android.support.v7.widget.Toolbar 
      android:id="@+id/toolbar" 
      android:layout_width="match_parent" 
      android:layout_height="?attr/actionBarSize" 
      android:background="?attr/colorPrimary" 
      app:layout_scrollFlags="scroll|enterAlways" 
      app:popupTheme="@style/AppTheme.PopupOverlay"> 

     </android.support.v7.widget.Toolbar> 

    </android.support.design.widget.AppBarLayout> 

    <android.support.v4.view.ViewPager 
     android:id="@+id/container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 

    <android.support.design.widget.FloatingActionButton 
     android:id="@+id/fab" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="end|bottom" 
     android:layout_margin="@dimen/fab_margin" 
     android:src="@android:drawable/ic_dialog_email" /> 

</android.support.design.widget.CoordinatorLayout> 

fragment_test.xml:

<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=".MainActivity$PlaceholderFragment" 
    android:background="#ffffff"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Fragment 1" 
     android:id="@+id/textView" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" /> 
</RelativeLayout> 

fragment_test2.xml:

<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=".MainActivity$PlaceholderFragment" 
    android:background="#ffffff"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Fragment 2" 
     android:id="@+id/textView2" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" /> 
</RelativeLayout> 

如图TestActivity2,系统应释放吐司示出当达到2页的数,将1加到每次访问该页面时的变量,就是这样。第一次滑动到第2页就是这样做的,但在随后的滑动中,输出会变得越来越怪异,同时显示几个敬酒,而不是仅显示一个。

附加到这一点,我注意到,当页面的数量是2,而不是3问题消失。

请问这个问题只发生在我?我怎么能有一个变通解决此?这是一个错误,或者是预期,有我丢失的东西?

回答

1

首先,我不得不说,有一个静态引用视图是内存泄漏和头痛的来源。考虑为文档和教程在这里你OnPageChangeListener在您的活动,然后将数据传递注册到您的片段:在手Communicating with other fragments

关于这个问题,这个问题也引起,因为你的静态ViewPager的。您在静态变量内添加对碎片的引用,因此这些碎片永远不会被垃圾收集,它们与OnPageChangeListener一起生活的时间与静态变量一样长。所以当ViewPager创建一个新的片段时,最后一个片段的OnPageChangeListener仍然存在,因此是多个吐司。

ViewPager默认负载2页到内存中,您可以通过setOffscreenPageLimit(int)改变这一点。当您有3页时,其中一页在您访问它时(或之前的页面)会被破坏并更新。这是我上面描述的根源。

您可以通过在您的活动中仅注册一个OnPageChangeListener来解决此问题,使ViewPager成为非静态字段,然后通过您可以在我最初指出的链接中了解到的方法通知您的更改的片段您。

或者,您可以看一下EventBus与您的沟通片段的另一种方式。

+0

我已经发布和删除这个问题了几天,你一个答案只有一个,非常感谢你! 我在Android开发中独自一人,我不想挑剔,但我们能保持联系吗?我保证,如果我有一个问题,我无法以任何方式工作,我只会打扰你。 –

+0

很高兴能有所帮助。 不幸的是,我现在不可能做到这一点。 StackOverflow是我可以提供帮助的唯一地方。 祝你好运,快乐的编码! @LuchitoMarcano – Avsector