在我的项目中,我有几个屏幕(片段),我想给片段元素(视图)提供动画。我使用了view pager和viewpager适配器和片段。我面临的主要问题 -
代码有问题吗?
这是 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
由于
答案 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) {
}
});
设置应保留在页面两侧的页数 处于空闲状态的视图层次结构中的当前页面。页面超出此范围 在需要时,将从适配器重新创建限制。
这是作为优化提供的。如果您事先知道这个号码 您将需要支持或具有延迟加载机制的页面 放在你的页面上,调整这个设置可以带来好处 感知到的分页动画和交互的平滑性。如果你有 少量页面(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);
}
}
我希望这会有所帮助。快活的编码!