想要在viewpager页面上启动动画,但页面正在预加载

时间:2016-03-12 11:08:19

标签: java android android-fragments android-viewpager fragment

在我的项目中,我有几个屏幕(片段),我想给片段元素(视图)提供动画。我使用了view pager和viewpager适配器和片段。我面临的主要问题 -

  1. 在开始加载2页时就像启动时一样,它正在加载第1页和第2页。如果要刷到第二页,则会自动加载第3页。
  2. 我需要显示正在使用Universal tween engine的视图(RelativeLayout)的动画。
  3. 代码有问题吗?

    这是 MainActivity.java 代码 -

        public class MainActivity extends FragmentActivity {    
        ViewPager viewPager;
        PagerAdapter adapter;
        CirclePageIndicator mIndicator;
        private int mWidthScreen;
        private int mHeightScreen;
        private Bundle bundle;
        private List<Fragment> frgScreens;
        private int selectedtheme;
        private Handler mHandler = new Handler();
    
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.viewpager_main); // Get the view from viewpager_main.xml        
            buildargument();        
            initialisePaging(); // Page creating function       
        }
    
        private void initialisePaging(int theme) {
            viewPager = (ViewPager) findViewById(R.id.pager);       
            frgScreens = new Vector<Fragment>(); // clearing old entries        
            viewPager.setOffscreenPageLimit(0);
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
                    //Loading fragment # position
    
                    //Instead of starting animation from onCreate start it from here 
                    //Only for the first time (for page 1) this callback will not trigger
                }
    
                @Override
                public void onPageSelected(int position) {
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
                }
            });
    
            frgScreens = this.basicThemes();
            // Bind result to ViewPagerAdapter
            adapter = new ViewPagerAdapter(this.getSupportFragmentManager(), frgScreens);
            this.viewPager.setAdapter(adapter);
        }
    
        /*
         * Basic fragments
         */
        private List<Fragment> basicThemes() {
            // declaring fragments Group Basic
            Fragment frgBasic1 = Fragment.instantiate(this, Basic1.class.getName());
            Fragment frgBasic2 = Fragment.instantiate(this, Basic2.class.getName());
            Fragment frgBasic3 = Fragment.instantiate(this, Basic3.class.getName());
            Fragment frgBasic4 = Fragment.instantiate(this, Basic4.class.getName()); 
            Fragment frgBasic5 = Fragment.instantiate(this, Basic5.class.getName()); 
    
            // Passing arguments
            frgBasic1.setArguments(bundle);
            frgBasic2.setArguments(bundle);
            frgBasic3.setArguments(bundle);
            frgBasic4.setArguments(bundle); 
            frgBasic5.setArguments(bundle);
    
    
    
            // Loading screens into Fragment list
            List<Fragment> frgBasicScreens = new Vector<Fragment>();
    
            frgBasicScreens.add(frgBasic1);
            frgBasicScreens.add(frgBasic2);
            frgBasicScreens.add(frgBasic3);
            frgBasicScreens.add(frgBasic4); 
            frgBasicScreens.add(frgBasic5);
    
        return frgBasicScreens;
    
    }
    
    private void getScreenHeightWidhth() {
        DisplayMetrics localDisplayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);
        this.mWidthScreen = localDisplayMetrics.widthPixels;
        this.mHeightScreen = localDisplayMetrics.heightPixels;
        mHandler.post(
                new DisplayToast(this, "Width Screen:" + mWidthScreen + ". Height Screen: " + mHeightScreen + "."));
    }
    
    private void buildargument() {
        this.bundle = new Bundle();
        bundle.putInt("mWidthScreen", this.mWidthScreen);
    }   
    
    @Override
    protected void onResume() {
        super.onResume();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
    }}
    

    现在 ViewPagerAdapter.java

    public class ViewPagerAdapter extends FragmentPagerAdapter {    
    private List<Fragment> screens; 
    
    public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments ) {
        super(fm);      
        this.screens = fragments;       
    }
    
    @Override
    public Fragment getItem(int pos) {
        // getting the position of the item
        return this.screens.get(pos);       
    }
    
    @Override
    public int getCount() {
        // Getting the size of screen passed
        return this.screens.size();
    }}
    

    skinbase.java 是所有基础知识屏幕上常用的一些共享方法。

    public abstract class SkinsBase extends Fragment
    {
     protected int mWidthScreen;
     protected int mHeightScreen;
     public int skinHeight;
     public int skinWidth;
     public final int textShadowSize = 2;
     .................
     }
    

    现在 basic1.java

    public class Basic1 extends SkinsBase { 
    private RelativeLayout mBlueBackground;
    private Handler mHandler = new Handler();
    private static final String TAG = "Basic1";
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }       
        mContext = container.getContext();
        View v = inflater.inflate(R.layout.blank_viewpager_item, container, false);
        mLayoutForeground = (RelativeLayout) v.findViewById(R.id.relative);
    
        mBlueBackground = initshape(getResources().getColor(R.color.transparent_blue_80),this.mWidthScreen, (int) (0.10F * this.mWidthScreen), 0,(int) (0.12F *this.mWidthScreen));     
        this.mLayoutForeground.addView(this.mBlueBackground);   
    
        Log.e(TAG, "Inside basic 1 ");
        return v;
    }
    
    
    
    public RelativeLayout initshape(int intColor,int intWidthscreen, int intHeight, int intMerginLeft,int intMerginTop) {
        RelativeLayout localRelativeLayout = new RelativeLayout(this.mContext);             
        localRelativeLayout.setBackgroundColor(intColor);       
        RelativeLayout.LayoutParams localLayoutParams = new RelativeLayout.LayoutParams(intWidthscreen, intHeight);
        localLayoutParams.setMargins(intMerginLeft, intMerginTop, 0, 0);
        localRelativeLayout.setLayoutParams(localLayoutParams);         
        return localRelativeLayout;
    }   
    
    public void onResume() {
        super.onResume();
    }
    @Override
    public void onPause() {
        super.onPause();
    }}
    

    其他 basic2.java,basic3.java,basic4.java ..... 的方式与 basic1.java

    类似

    我需要将动画应用于 RelativeLayout 。可能吗?而且我希望在页面加载之前没有动画的开始。如果需要更多信息,请评论。 请不要downvote

    由于

2 个答案:

答案 0 :(得分:1)

view-pager的默认行为是它从当前页面的两侧预加载至少1页。请参阅以下链接

ViewPager.setOffscreenPageLimit(0) doesn't work as expected

所以你能做的就是开始动画onCreate从onPageScrolled回调

开始
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        //Loading fragment # position

        //Instead of starting animation from onCreate start it from here 
        //Only for the first time (for page 1) this callback will not trigger
    }

    @Override
    public void onPageSelected(int position) {
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
});

请参阅setOffscreenPageLimit

  

设置应保留在页面两侧的页数   处于空闲状态的视图层次结构中的当前页面。页面超出此范围   在需要时,将从适配器重新创建限制。

     

这是作为优化提供的。如果您事先知道这个号码   您将需要支持或具有延迟加载机制的页面   放在你的页面上,调整这个设置可以带来好处   感知到的分页动画和交互的平滑性。如果你有   少量页面(3-4),您可以一次保持活动状态,   在新创建的视图子树的布局中花费的时间会减少   用户来回翻页。

     

您应该保持此限制,特别是如果您的网页很复杂   布局。 此设置默认为1。

答案 1 :(得分:0)

在我的每个页面/片段中覆盖setUserVisibleHint()都对我有用。您只需在view.startAnimation(animation)内部调用setUserVisibleHint()。但是,这种方法存在一个问题:

  

在片段中,setUserVisibleHint()在被调用之前   onCreateView()onViewCreated

其含义是,当片段首次启动并在view.startAnimation(animation)中调用setUserVisibleHint()时,视图和动画都将为null,并且应用程序将崩溃。


那您如何解决此问题?

在您的每个页面/片段中,只需声明一个全局布尔值(我们称其为fresh_load),然后使用此布尔值检查是否是第一次加载该片段。这是一个例子:

boolean fresh_load = true;
Animation move;
ImageView car;

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

    // init move and car variables

    if(fresh_load) {
        car.startAnimation(animation);
        fresh_load = false;
    }

    return view;
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if((isVisible() && animation != null) && !fresh_load) {
        car.startAnimation(move);
    }
}

我希望这会有所帮助。快活的编码!