我已彻底研究过这些问题,但还未找到答案。另外,我的借口是因为我不是母语,因此我的英语很差。
问题:在我的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);
}
有关如何在屏幕上“滑入”列表视图的行的任何建议?非常感谢!
答案 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);
}