在动画上,listview的一部分未显示

时间:2014-02-06 16:07:37

标签: android listview layout android-listview

我已彻底研究过这些问题,但还未找到答案。另外,我的借口是因为我不是母语,因此我的英语很差。

问题:在我的android布局中,我们在status_text下面有一个带有listview的status_text。触摸status_text时,我们会在status_text和listview上设置“向下移动”动画,以便只有第一个列表视图行仍在屏幕上。列表视图现在仍然可用。

再次触摸status_text时,我们将status_text和listview向上移动,以便listview使用一半的屏幕。

我们面临的问题是,在“向上移动”期间,只有第一行是动画的。 “向上移动”后,其他行突然出现。

我们希望拥有的是“向上移动”,以前隐藏的行会滑动到屏幕上。

布局: 我们正在使用这种布局(略微简化以专注于手头的问题):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_declareren_choose_verzekerden"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- Dummy anchor to put top of listview in the middle of the screen -->
    <RelativeLayout
        android:id="@+id/anchor"
        style="@style/anchor_status_container"
        android:layout_centerVertical="true" >

    </RelativeLayout>


    <!-- Example image -->
    <ImageView
        android:id="@+id/my_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/footer"
        android:adjustViewBounds="true"
        android:contentDescription="@string/image_description"
        android:scaleType="centerCrop"
        android:src="@drawable/empty" />


    <!-- Clickable text which moves up and down on click -->
    <RelativeLayout
        android:id="@+id/status_container"
        style="@style/status_container"
        android:layout_alignTop="@id/anchor"
        android:background="@color/white" >

        <TextView
            android:id="@+id/status_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginRight="@dimen/spacing_sml"
            android:layout_alignTop="@id/status_container" />

    </RelativeLayout>

    <!-- Listview which moves up and down with the status_container -->

    <RelativeLayout
        android:id="@+id/listView_container"
        style="@style/padding_content_horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/status_container"
        android:background="@color/white" >

        <ListView
            android:id="@+id/mylistView"
            style="@style/myListviewStyle"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:divider="@null"
            android:dividerHeight="0dp" />
    </RelativeLayout>


    <!-- Footer with buttons -->

    <RelativeLayout
        android:id="@+id/footer_button_container"
        style="@style/footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/button_again"
            style="@style/btn_secondary"
            android:layout_width="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="@string/opnieuw"
            android:visibility="gone" />

        <Button
            android:id="@+id/button_next"
            style="@style/btn_primary"
            android:layout_width="wrap_content" />
    </RelativeLayout>

</RelativeLayout>

代码(再简单一点,只显示手边的问题。删除了一些淡入/淡出和旋转):

   // The code
   @Override
   public void onClick(View view)
   {
      int viewId = view.getId();
      if (viewId == R.id.status_container)
      {
         // Someone clicked the text, move the statusbar (and so the listview) up or down
         if (this.viewIsInUpperPosition)
         {
            startStatusAnimation();
         }
      }
   }

   private void startStatusAnimation()
   {
      if (animationIsRunning)
      {
         return;
      }
      setAnimationIsRunning(animValues.START);

      // 0. Initialisation
      final View statusContainer = (View) getView().findViewById(R.id.status_container);
      final View listContainer = (View) getView().findViewById(R.id.listView_container);
      final ListView listView = (ListView) getView().findViewById(R.id.myListView);
      final View footerButtonContainer = (View) getView().findViewById(R.id.footer_button_container);

      // 1. Calculate distance for animation
      if (toggleViewDistance == 0)
      {
         int listViewContainerHeight = listContainer.getHeight();
         int footerHeight = footerButtonContainer.getHeight();
         int spaceForListView = listViewContainerHeight - footerHeight;
         toggleViewDistance = spaceForListView;
      }

      // 2. Decide if the movement is up or down
      float translationDistance = (viewIsInUpperPosition) ? toggleViewDistance : 0 - toggleViewDistance;

      // 3. Create the animation
      TranslateAnimation yMove = new TranslateAnimation(0, 0, 0, translationDistance);
      yMove.setDuration(animValues.ANIMATION_Y_DURATION);
      yMove.setInterpolator(new AccelerateDecelerateInterpolator());

      // Do here something with scaling and rotating of other objects, not relevant for the question on StackOverflow

      // 4. Actions after animation

      yMove.setAnimationListener(new AnimationListener()
         {
            @Override
            public void onAnimationEnd(Animation arg0)
            {
               // Fade de listView in als je van onderen naar boven animeert
               if (!viewIsInUpperPosition)
               {
                  // Do some fading, outside scope of question
               }

               // Create layout after the animation
               RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) statusContainer.getLayoutParams();
               if (viewIsInUpperPosition)
               {
                  // View was previously in upper position, now put the statusbar aligned with the footer
                  params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
                  params.addRule(RelativeLayout.ABOVE, footerButtonContainer.getId());
               }
               else
               {
                  // View was previously in bottom position, so put it under the anchor
                  params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
                  params.addRule(RelativeLayout.ALIGN_TOP, R.id.anchor);
                  }
               }
               statusContainer.setLayoutParams(params); // Set the new layout params

               viewIsInUpperPosition = !viewIsInUpperPosition; 
               setAnimationIsRunning(animValues.END);
            }

            @Override
            public void onAnimationRepeat(Animation arg0)
            {
               // Empty
            }

            @Override
            public void onAnimationStart(Animation arg0)
            {
               // empty
            }
         });

      // 5. Start the animation
      statusContainer.startAnimation(yMove);
      listContainer.startAnimation(yMove);
   }

有关如何在屏幕上“滑入”列表视图的行的任何建议?非常感谢!

1 个答案:

答案 0 :(得分:0)

我明白了。所以我在回答我自己的问题,以防有人偶然发现这个问题。

需要做的是列表视图是在屏幕外绘制的。这可以通过使用listview的屏幕外坐标调用measure-和layout-方法来强制执行。

这修复了我的代码:

  // 5a. Draw the listview off-screen
  if (translationDistance < 0)
  {
     // Do this only when the listview is sliding up, e.g. sliding the window in.

     int listViewContainerVerticalPos = listContainer.getTop(); // De positie van de listview

     // The required height of the listview
     int listContainerHeight = (int) Math.abs(translationDistance) + statusContainer.getHeight();

     int measureWidth = View.MeasureSpec.makeMeasureSpec(listContainer.getWidth(), View.MeasureSpec.EXACTLY);
     int measureHight = View.MeasureSpec.makeMeasureSpec(listContainerHeight, View.MeasureSpec.EXACTLY);
     listContainer.measure(measureWidth, measureHight);

     listContainer.layout(0, listContainerVerticalPos, listContainer.getMeasuredWidth(), listContainerVerticalPos
           + listContainerHeight);
  }