做推片段动画

如何通过下一个片段进行推送当前片段的动画

这是我想要的动画: 在此处输入图像描述

我当前的动画代码只是将第一个片段与第二个片段重叠,它没有像图片中那样推动它

这是代码:

result_list.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView av, final View view, final int i, long i2) { result_list.setEnabled(false); view.animate().setDuration(300).translationX(widthListView).alpha(0). withEndAction(new Runnable() { @Override public void run() { //setResult(Activity.RESULT_OK,new Intent().putExtra("bussStopCode", data.get(i).getStopCode()).putExtra("bussStopName", data.get(i).getStopName())); ////int get 1 //data.remove(i); int temporaryInteger = i; listLastPostion = temporaryInteger; //customAdapter.notifyDataSetChanged(); //view.setTranslationX(0); Log.d("data",conreq.getCollectedData().getBusRouteSetData().get(temporaryInteger - 1).getRouteHeading()); Bundle bundle = new Bundle(); bundle.putString("busdestination", conreq.getCollectedData().getBusRouteSetData().get(temporaryInteger-1).getRouteHeading()); bundle.putString("busnumber", conreq.getCollectedData().getBusRouteSetData().get(temporaryInteger-1).getRouteNo()); Fragment fragment = new FragmentNextTripForStop(); fragment.setArguments(bundle); FragmentTransaction fragmentManager = getFragmentManager().beginTransaction(); fragmentManager.setCustomAnimations(R.anim.right_left_anim_x_left,R.anim.right_left_anim_x_right,R.anim.left_right_anim_x_left,R.anim.left_right_anim_x_right); fragmentManager.add(R.id.fragment_searched_data_xml, fragment).addToBackStack(null).commit(); // finish(); //overridePendingTransition(R.anim.right_left_anim_x_left,R.anim.right_left_anim_x_right); } }); }}); 

虽然这个问题是重复的,但是对于这个问题提供的答案对许多观众来说并不适用,并要求他们在结束时做出一些假设。

考虑到许多应用程序中存在此function,这是一个很好的问题,但它需要非常复杂的答案。 我将尝试将答案分解为一系列分隔步骤,以确保它是可重复的!

问题

阻碍我们大多数人轻易做到这一点的问题是复合性质。 要完全理解这个问题,让我列出问题:

  • 我们不应该使用典型的动画框架,因为FragmentManagerFragmentTransaction类提供了一个方便的方法, setCustomAnimations(int, int, int int) ,它需要ObjectAnimators
  • 此外,我们不能在ObjectAnimators使用百分比标记(传统方法)
  • 最后,我们只能在运行时确定屏幕宽度,因此必须在我们自己的布局中具有自定义function

解决方案

为了解决这个问题并提供所需的沉浸式体验,我们必须从多个角度解决这个问题。 接下来的几个步骤将解释如何获取此function!

  1. 我们首先需要为每个Fragment定义一个自定义布局,因为我们必须具有对屏幕宽度的运行时访问权限,以及一个基于此宽度操纵View (布局)的x位置的自包含方法。

    FractionTranslateLinearLayout.java

     public class FractionTranslateLinearLayout extends LinearLayout{ private int screenWidth; private float fractionX; protected void onSizeChanged(int w, int h, int oldW, int oldh){ // Assign the actual screen width to our class variable. screenWidth = w; super.onSizeChanged(w, h, oldW, oldH); } public float getFractionX(){ return fractionX; } public void setFractionX(float xFraction){ this.fractionX = xFraction; // When we modify the xFraction, we want to adjust the x translation // accordingly. Here, the scale is that if xFraction is -1, then // the layout is off screen to the left, if xFraction is 0, then the // layout is exactly on the screen, and if xFraction is 1, then the // layout is completely offscreen to the right. setX((screenWidth > 0) ? (xFraction * screenWidth) : 0); } } 
  2. 现在,由于我们有一个特殊的布局,允许我们根据屏幕的物理宽度进行转换,我们可以在相关的Fragment XML文件中使用它。

    fragment_1.xml

        

    fragment_2.xml

        
  3. 然后,我们必须创建将包含实现转换的逻辑的Fragment类。

    Fragment1.java

     public class Fragment1 extends Fragment { public View onCreateView(LayoutInflater inf, ViewGroup vg, Bundle b){ // Simply inflate the View from the .xml file. return inf.inflate(R.layout.fragment_1, vg, false); } } 

    Fragment2.java

     public class Fragment2 extends Fragment { public View onCreateView(LayoutInflater inf, ViewGroup vg, Bundle b){ // Simply inflate the View from the .xml file. return inf.inflate(R.layout.fragment_2, vg, false); } public void onActivityCreated (Bundle savedInstanceState){ View v = getView(); FractionTranslateLinearLayout layout; layout = (FractionTranslateLinearLayout) v.findViewById(R.id.layout); // Move the entire View off to the right of the screen for now. layout.setFractionX(1.0f); } } 
  4. 现在让我们创建一个objectAnimator .xml文件,我们将用它们在屏幕上翻译View 。 请注意,我们需要其中的四个文件,因为每个进程需要一个(out和in),每侧需要一个(左侧和右侧)。

    slide_left_out.xml

      

    slide_right_out.xml

      

    slide_left_in.xml

      

    slide_right_in.xml

      

请注意,这些文件夹必须放在项目结构的“res / animator”目录中。

  1. 创建容器布局,当我们在它们之间转换时,它将容纳每个Fragment

    main.xml中

      
  2. 现在,我们必须创建将所有内容组合在一起的Activity

    Main.java

     public class Main extends Activity { private boolean showingFirstFragment; public void onCreate(Bundle savedInstanceState){ setContentView(R.layout.main); FragmentManager manager = getFragmentManager(); FragmentTransaction trans = manager.beginTransaction(); // Keep track of which Fragment we are facing. showingFirstFragment = true; // Add the first Fragment to the container. trans.add(R.id.main_container, new Fragment1(), "fragment_1"); trans.commit(); } public void onBackPressed(){ // Override the back button functionality to simply switch // Fragments. Note that this would normally be done in a click // click listener. switchFragments(); } private void switchFragments(){ FragmentManager manager = getFragmentManager(); FragmentTransaction trans = manager.beginTransaction(); // Set the animations that will emulate the functionality you // requested. int rightIn = R.animator.slide_right_in; int rightOut = R.animator.slide_right_out; int leftIn = R.animator.slide_left_in; int leftOut = R.animator.slide_left_out; // Note that we pass in 4 animations here. Please see the // documentation on this method as it is critical to the // understanding of this solution. trans.setCustomAnimations(rightIn, leftOut, leftIn, rightOut); if(showingFirstFragment){ int container = R.id.main_container; // Show the second Fragment. trans.replace(container, new Fragment2(), "fragment_2"); trans.commit(); showingFirstFragment = false; } else{ // Show the first Fragment by popping the back stack! manager.popBackStack(null); showingFirstFragment = true; } } } 

在此代码示例中, 此类被大量使用。 它的方法对于执行过程至关重要!

一些考虑因素

请注意,我在这里做了一些假设,并且这段代码非常独特:

  • 此示例使用原始Fragment类,因此除非进行必要的修改,否则将无法使用支持包。
  • 此示例要求您使用的是Android API 13.0或更高版本。
  • 这个例子的目的是提供信息,并希望解释这里涉及的问题。 在您自己的编辑器中拼凑代码是您应该自行决定的事情!

希望这里有足够的细节来回答你的问题。 如果您需要,请告诉我。

此时,应该有足够的代码来实现您自己的解决方案。 我确实在没有Eclipse编辑器的情况下输入了它,所以如果有任何错误,请提前接受我的道歉!