1

我有一个视图模板,它由 mainRelativeLayout和 2组成,FrameLayouts用于片段。(我附上了一张图像来可视化我的模板。)红色是RelativeLayout,棕色和绿色是FrameLayouts

现在,棕色部分包含了一个很重但很漂亮的网格列表。绿色部分包含一个简单LinearLayoutImage(灰色)、Seekbar(蓝色)和一个TextView(粉红色)。

UI 线程上的SeekBar进度每 1 秒更新一次。我注意到网格列表的滚动每 1 秒就会冻结。通过进行一些跟踪视图调试,我注意到该列表每 1 秒重新绘制一次。

最重要的是,我从开发者菜单中启用了实际设备上的“显示布局更新”选项。它显示了更有趣的视图 - 上面的所有内容都Seekbar被重新绘制。为什么 SeekBar 视图更新会重绘上面的所有视图?

我无法显示很多代码,但我执行标准片段附件,然后在片段中创建一个具有特定睡眠期的线程,然后更新 ui-thread 上的搜索栏进度。

如果您需要更多信息,请告诉我,我会尝试更新线程。我今天花了 4-5 个小时试图理解它为什么会这样做——但没有成功......

主模板非常简单。就像是:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bgwood"
android:orientation="vertical" >


<FrameLayout
android:id="@+id/top_container"
android:layout_width="match_parent"
android:layout_height="match_parent" 
android:layout_above="@+id/bottom_container" />



<FrameLayout
android:id="@+id/bottom_container"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#ff111111" />

</RelativeLayout>

在此处输入图像描述

编辑:更多信息...

底部片段(绿色)包含类似于以下视图结构的内容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/player_playercontainer"
    android:layout_width="fill_parent"
    android:layout_height="115dp"
    android:layout_gravity="bottom"
    android:background="@drawable/bg_player"
    android:gravity="center"
    android:baselineAligned="false"
    android:orientation="horizontal" >

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center|center_vertical"
        android:background="#000000"
        android:scaleType="fitXY"
        android:src="@drawable/hdd" />


    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal"
        android:layout_weight="0.64"
        android:gravity="center"
        android:orientation="vertical"
        android:paddingLeft="10dp"
        android:paddingRight="10dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingRight="5dp"
            android:shadowColor="#cc111111"
            android:shadowDx="1"
            android:shadowDy="1"
            android:shadowRadius="1"
            android:text="unknown"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="#888"
            android:textSize="13dp" />


        <ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:max="100" />


    </LinearLayout>



</LinearLayout>

将片段附加到底部布局:

if (bundle == null) {
        FragmentTransaction fragmentTransaction = mManager.beginTransaction();  
        SourceListFragment fragment = BottomFragment();
        fragmentTransaction.add(R.id.bottom_container, fragment).commit();
} 

更新片段中的搜索栏:

/* Called every 1 sec */
void updateCallback(final int progress) {

    getActivity().runOnUiThread(new Runnable() {
        public void run() {
        if (seekBarView == null) {
            seekBarView = (SeekBar) view.findViewById(R.id.progressBar);
        } 
        seekBarView.setProgress()
    });

}
4

3 回答 3

1

我无法显示很多代码,但我执行标准片段附件,然后在片段中创建一个具有特定睡眠期的线程,然后更新 ui-thread 上的搜索栏进度。

尝试使用 aHandler更新ProgressBar

定义以下全局变量:

Handler updateHandler;

// loop control variable
boolean shouldStop;

Runnable updateRunnable;

初始化变量:

updateHandler = new Handler();

shouldStop = false;

updateRunnable = new Runnable() {

    @Override
    public void run() {
        if (!shouldStop) {

            // Post this Runnable again with a delay of 1000 milliseconds
            updateHandler.postDelayed(this, 1000L);

            // Update ProgressBar
            updateCallback(Your_Progress_Value);
        }
    }
};

// Start the update process
updateHandler.post(updateRunnable);

在这种情况下,您不需要指定运行更新的线程:

/* Called every 1 sec */
void updateCallback(final int progress) {
    if (seekBarView == null) {
        seekBarView = (SeekBar) view.findElementById(R.id.progressBar);
    } 
    seekBarView.setProgress(...);
}

当您需要结束更新过程时,将使用该boolean变量。shouldStop将其设置为true,更新将停止。

注意:您ProgressBar的布局中有一个小部件,并且您的代码使用SeekBar. 你能在你的帖子中更正一下吗?另一件事,没有带有签名的findElementById(int)方法View。这是您的实际代码吗?

于 2013-09-05T23:05:12.993 回答
1

问题是 TextView 宽度设置为 wrap_content ,因此每次值更新时都会重新绘制它。问题是如果一个子元素被重绘,即那个TextView,那么所有的父视图也将被强制重绘。

所以基本上,将动态视图设置为特定大小或 match_parent。

于 2013-12-18T00:39:20.410 回答
0

我想我知道它在做什么,通过使用android:layout_above你的顶部片段在底部之后绘制。所以它受到底部更新的影响。

改用android:layout_alignParentTop="true"应该可以防止这种情况。

如果您还没有看过它,那么您绝对应该查看I/O 讨论中关于自定义视图的内容。使用RelativeLayouts 可能是一场噩梦,但他们在解释它们的工作原理方面做得非常出色。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bgwood"
android:orientation="vertical" >


<FrameLayout
android:id="@+id/top_container"
android:layout_width="match_parent"
android:layout_height="match_parent" 
android:layout_alignParentTop="true"
android:layout_marginBottom="300dp"  />



<FrameLayout
android:id="@+id/bottom_container"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#ff111111"
android:layout_alignParentBottom="true" />

</RelativeLayout>
于 2013-09-05T09:39:33.517 回答