gpt4 book ai didi

android - 3 Pane 布局 fragment 动画卡顿

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:54:22 24 4
gpt4 key购买 nike

实现信息:我已经按照 CommonsWare 对他自己的问题发布的回复实现了 3 Pane 布局:Complete Working Sample of the Gmail Three-Fragment Animation Scenario?

一般来说,我的布局由以下级别(1 到 3)组成:

  1. 主 Activity
  2. SlidingMenu(Side Drawer UI 模式) fragment 隐藏在左侧,ContentFragment 作为包含 3 Pane 布局的 fragment 。
  3. ContentFragment 中:LeftListFragment(每行有 3 个 TextView),MiddleListFragment(每行有 8 个 TextView),DetailFragment

LeftListFragmentMiddleListFragment 使用 CursorLoaders 从每个列表中的 ContentProvider 加载数据。 DetailFragment 还会在需要时调用带有数据的游标。所以我什至没有实现自定义 Adapter(这样设计更好)。然后我添加了 3 Pane 布局 + 动画。就工作而言,它按预期工作,没有问题。 动画时间为 500 毫秒。

问题:动画有点卡顿。一些丢帧。当 Left 和 Middle 都可见并且我单击 Middle 列表项以打开 Detail 时;以及当我点击返回按钮再次查看左侧和中间列表时(实际上没有加载任何内容)。

我尝试过的:

  1. 删除了在 DetailView 中加载 fragment 的代码。我只需点击 MiddleFragment 中的一个项目,动画就会开始,实际上没有加载任何细节。仍然口吃。此外,当回击时,没有加载任何内容,它仍然断断续续,所以我认为加载程序/游标不是造成这种情况的原因。
  2. 我使用 dumpsys gfxinfo 查看计算每一帧的平均时间(以毫秒为单位)。实际上,计算的平均时间为 18 毫秒,高于 16 毫秒阈值。那么这是否意味着口吃是因为在动画时再次绘制列表所花费的时间?如果是这样,为什么?我的意思是......我在行 View 中根本没有任何图像。而且我不能搞砸适配器代码,因为我没有写任何...
  3. Animation 时间从 500 毫秒减少到 200 毫秒。如果您仔细观察它,它仍然会卡顿,只是速度更快。

编辑: 我从下面的 rightPaneWidth 切换到 leftPaneWidth(是的,删除了重新标注尺寸的动画),卡顿现在消失了.列表仍然向左滑动,但宽度并没有变小。因此,如果现在不再出现卡顿现象,是否意味着我的代码中的 ObjectAnimator 存在问题?

ObjectAnimator.ofInt(this, "middleWidth", rightPaneWidth, leftPaneWidth)
.setDuration(ANIM_DURATION).start();

感谢您的宝贵时间!

3 Pane 布局的代码:

package com.xyz.view.widget;

import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.LinearLayout;


public class ThreePaneLayout extends LinearLayout
{
private View leftView = null;
private View middleView = null;
private View rightView = null;

private static final int ANIM_DURATION = 500;
private int leftPaneWidth = -1;
private int rightPaneWidth = -1;


// -------------------------------------------------------------------------------------------
// -------------- Constructor
// -------------------------------------------------------------------------------------------


public ThreePaneLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
setOrientation(HORIZONTAL);
}

@Override
public void onFinishInflate()
{
super.onFinishInflate();
leftView = getChildAt(0);
middleView = getChildAt(1);
rightView = getChildAt(2);
}


// -------------------------------------------------------------------------------------------
// -------------- Public methods
// -------------------------------------------------------------------------------------------


public View getLeftView()
{
return leftView;
}

public View getMiddleView()
{
return middleView;
}

public View getRightView()
{
return rightView;
}

@SuppressLint("NewApi")
public void hideLeft()
{
if (leftPaneWidth == -1)
{

leftPaneWidth = leftView.getWidth();
rightPaneWidth = middleView.getWidth();
resetWidget(leftView, leftPaneWidth);
resetWidget(middleView, rightPaneWidth);
resetWidget(rightView, rightPaneWidth);
requestLayout();
}
translateWidgets(-1 * leftPaneWidth, leftView, middleView, rightView);
ObjectAnimator.ofInt(this, "middleWidth", rightPaneWidth, leftPaneWidth)
.setDuration(ANIM_DURATION).start();
}

@SuppressLint("NewApi")
public void showLeft()
{
translateWidgets(leftPaneWidth, leftView, middleView, rightView);
ObjectAnimator.ofInt(this, "middleWidth", leftPaneWidth, rightPaneWidth)
.setDuration(ANIM_DURATION)
.start();
}


// -------------------------------------------------------------------------------------------
// -------------- Private methods
// -------------------------------------------------------------------------------------------


private void setMiddleWidth(int value)
{
middleView.getLayoutParams().width = value;
requestLayout();
}

@TargetApi(12)
private void translateWidgets(int deltaX, View... views)
{
for (final View view : views)
{
ViewPropertyAnimator viewPropertyAnimator = view.animate();
viewPropertyAnimator.translationXBy(deltaX)
.setDuration(ANIM_DURATION);
}
}

private void resetWidget(View view, int width)
{
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)view.getLayoutParams();
layoutParams.width = width;
layoutParams.weight = 0;
}
}

ContentFragment 的 XML:

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

<FrameLayout
android:id="@+id/fragment_content_framelayout_left"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />

<FrameLayout
android:id="@+id/fragment_content_framelayout_middle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="7" />

<FrameLayout
android:id="@+id/fragment_content_framelayout_right"
android:layout_width="0dp"
android:layout_height="match_parent" />
</com.xyz.view.widget.ThreePaneLayout>

最佳答案

问题不在于 ObjectAnimator,而在于您的应用程序在动画的每一帧上都做了太多的事情。具体来说,您正在为布局参数设置动画并在每一帧上请求布局。布局功能强大且有用......但除了最琐碎的 View 层次结构之外,布局可能非常昂贵。重要的是要避免在动画期间每帧进行昂贵的操作,而布局属于“昂贵”的类别。滑动东西很好(translationX/Y),淡入/淡出很好(alpha),但实际上把东西放在每一帧上?就说不。

关于android - 3 Pane 布局 fragment 动画卡顿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14665469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com