当用户点击按钮时,我需要为三个元素设置动画以显示其他信息。我有一个标签(TextView tvAvailableToPair)从按钮(Button bSearchForDevices)下面滑出 - 两者都以fill_parent的宽度开始 - 同时它同时向上滑动。我有完美的变化,但它没有动画:我通过SetLayoutParams实现了这一点:
bSearchForDevices.setText(R.string.bSearchForDevicesDiscoveryStartedText);
FrameLayout.LayoutParams lp_bSFD =
(FrameLayout.LayoutParams) bSearchForDevices.getLayoutParams();
int mWidthOfBSearchForDevices = lp_bSFD.width =
(int) Math.round(fMeasureScreenWidth * 0.4);
int mLeftMarginOfBSearchForDevices = lp_bSFD.leftMargin =
Math.round(fMeasureScreenWidth - (fHorizontalMargin + lp_bSFD.width));
bSearchForDevices.setLayoutParams(lp_bSFD);
lp_bSFD = (FrameLayout.LayoutParams) tvAvailableToPair.getLayoutParams();
lp_bSFD.width = mLeftMarginOfBSearchForDevices;
lp_bSFD.leftMargin = 0;
tvAvailableToPair.setLayoutParams(lp_bSFD);
ViewGroup.LayoutParams lp = llAvailableToPair.getLayoutParams();
lp.height = Math.round(getResources().getDimensionPixelSize(
R.dimen.llAvailableToPair_height_expanded) * MainActivity.displayMetrics.density);
我了解到FrameLayout允许您将元素放在不同的Z轴值上(在另一个元素的顶部或下面;覆盖或被另一个元素覆盖)。这是我活动的xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:id="@+id/rlDeviceListLayout"
android:background="@android:color/holo_blue_dark"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
<android.support.design.widget.AppBarLayout
android:id="@+id/ablToolbarLayout"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<LinearLayout>
<!-- Existing devices for user to select -->
</LinearLayout>
<!-- This is what needs to be animated up once user presses the button -->
<LinearLayout
android:id="@+id/llAvailableToPairLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="@dimen/llAvailableToPair_height_collapsed"
android:layout_alignParentBottom="true"
android:paddingTop="4dp">
<!-- This Layout is used to stack the button over the textview -->
<FrameLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginBottom="4dp">
<!-- We'll change the width of this programmatically so that it appears to
elegantly slide to the left -->
<TextView
android:id="@+id/tvAvailableToPair"
android:text="@string/tvAvailableToPair"
android:layout_width="fill_parent"
android:layout_height="@dimen/bSearchForDevices_height"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:inputType="none"
android:gravity="center"
android:foregroundGravity="left"
android:textSize="16sp"
android:textColor="#ffffff" />
<!-- We'll change the text, width and left of this so that it reveals the
textview under it. It needs to appear as if it were elegantly squeezed
toward the right -->
<Button
android:id="@+id/bSearchForDevices"
android:text="@string/bSearchForDevicesPreliminaryText"
android:layout_width="fill_parent"
android:layout_height="@dimen/bSearchForDevices_height"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:foregroundGravity="right"
android:visibility="visible"
android:theme="@style/Base.ThemeOverlay.AppCompat.Dark"
android:gravity="center" />
</FrameLayout>
<ListView
android:id="@+id/lvAvailableToPair"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:visibility="visible" />
</LinearLayout>
</RelativeLayout>
我正在改变的最后三个要素。使用SetLayoutParams保持文本居中(并且我缩短了按钮上的文本以允许更小的屏幕和标签 - 我需要在更改后对其进行动画处理,可能使用TextSwitcher Animate Text Using TextSwitcher In Android)。继续将这些更改变为动画,我不得不使用不同的方法:
bSearchForDevices.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FrameLayout.LayoutParams lpTVATP = (FrameLayout.LayoutParams) tvAvailableToPair.getLayoutParams();
Paint paint = new Paint();
AnimatorSet RevealAvailableDevices = new AnimatorSet();
float fMeasuretvAvailableToPairTextWidth = paint.measureText(tvAvailableToPair.getText().toString()); // Function returns dp, not pixels
float fMeasurebSearchForDevicesTextWidth = paint.measureText(bSearchForDevices.getText().toString());
float fMeasureScreenWidth = MainActivity.displayMetrics.widthPixels; // + 0.5f; // Extra 0.5 to simplify/speed up rounding w/o a lot of excess code (LoungeKatt, via https://stackoverflow.com/questions/1016896/get-screen-dimensions-in-pixels) and used on Google's Android docs for just this purpose @ https://developer.android.com/guide/practices/screens_support.html#dips-pels
float fHorizontalMargin;
// If the screen is cramped, we'll shorten the margins:
if (fMeasuretvAvailableToPairTextWidth > (fMeasureScreenWidth * 0.5)) {
fHorizontalMargin = (getResources().getDimension(R.dimen.activity_horizontal_margin_compressed) / MainActivity.displayMetrics.density);
} else {
fHorizontalMargin = (getResources().getDimension(R.dimen.activity_horizontal_margin) / MainActivity.displayMetrics.density);
}
/* This works PERFECTLY, but isn't animated:
bSearchForDevices.setText(R.string.bSearchForDevicesDiscoveryStartedText);
FrameLayout.LayoutParams lp_bSFD = (FrameLayout.LayoutParams) bSearchForDevices.getLayoutParams();
int mWidthOfBSearchForDevices = lp_bSFD.width = (int) Math.round(fMeasureScreenWidth * 0.4);
int mLeftMarginOfBSearchForDevices = lp_bSFD.leftMargin = Math.round(fMeasureScreenWidth - (fHorizontalMargin + lp_bSFD.width));
bSearchForDevices.setLayoutParams(lp_bSFD);
lp_bSFD = (FrameLayout.LayoutParams) tvAvailableToPair.getLayoutParams();
lp_bSFD.width = mLeftMarginOfBSearchForDevices;
lp_bSFD.leftMargin = 0;
tvAvailableToPair.setLayoutParams(lp_bSFD);
ViewGroup.LayoutParams lp = llAvailableToPair.getLayoutParams();
lp.height = Math.round(getResources().getDimensionPixelSize(R.dimen.llAvailableToPair_height_expanded) * MainActivity.displayMetrics.density);
*/
float fWidthOfbSearchForDevices = (float) ((fMeasureScreenWidth * 0.4));
float fWidthOftvATP = (fMeasureScreenWidth - ((fWidthOfbSearchForDevices * 1) + (fHorizontalMargin * 2)));
float fXOfbSearchForDevices = (fMeasureScreenWidth - (fWidthOfbSearchForDevices + (1 * fHorizontalMargin)));
Log.d(TAG, "...\nfMeasureScreenWidth = " + fMeasureScreenWidth + "\nfWidthOfbSearchForDevices = " + fWidthOfbSearchForDevices + "\nfHorizontalMargin = " + fHorizontalMargin +
"\nbSearchForDevices.getX() = " + bSearchForDevices.getX() + "\n (fXOfbSearchForDevices) X is going to be " + fXOfbSearchForDevices);
ObjectAnimator aniButtonMove = ObjectAnimator.ofInt(bSearchForDevices, "Left", (int) fXOfbSearchForDevices);
bSearchForDevices.setPivotX(fXOfbSearchForDevices + (fWidthOfbSearchForDevices / 2)); // No effect: To be in the center of where the button will end up at.
ObjectAnimator aniTextViewResize = ObjectAnimator.ofInt(tvAvailableToPair, "Right", (int) fXOfbSearchForDevices);
Log.d(TAG, "tvAvailableToPair's width = " + tvAvailableToPair.getWidth() + " tvAvailableToPair is supposed to be " + fWidthOftvATP + "\nWidth of bSearchForDevices = " + bSearchForDevices.getWidth());
RevealAvailableDevices.play(aniTextViewResize).with(aniButtonMove);
RevealAvailableDevices.start();
这会生成一个正确移动textview和按钮边界的动画,但不会将文本居中到这些元素的新边界(边缘/左右坐标):我的按钮现在显示很多前导空在它之前的空间显示S,E和“搜索设备”的A的一半;换句话说,它被剪裁了。我需要它保持居中(就像使用SetLayoutParams时一样)。这同样适用于textview:“可用设备”的最后5个字母被剪掉。
有没有更好的方法来创建这个有三个元素改变形状的动画(最好也可以更改按钮的文字)?我已经尝试过ScaleX,但我无法正确同步,因为它在中心枢转而不向右侧滑动,也不会在缩小时滑动textview ...也许是ScaleX但是将枢轴更改为左边缘..或者也许是PropertyValuesHolder?
2016/3/15更新: 这就是我所拥有的:https://www.dropbox.com/s/n14hed6xcknfh9b/SS_20160315_135938.mp4?dl=0
我需要它看起来像post animation