我有一个视图模板,其中包含用于片段的主RelativeLayout
和2 FrameLayouts
。(我附加了一个图像以显示我的模板。)红色是RelativeLayout
,棕色和绿色是FrameLayouts
。
现在,棕色部分包含一个非常沉重但很漂亮的网格列表。绿色部分包含一个简单的LinearLayout
Image
(灰色),Seekbar
(蓝色)和TextView
(粉红色)。
每1秒在UI线程上更新SeekBar
进度。我注意到网格列表的滚动冻结了1秒钟。通过做一些traceview调试,我注意到列表每1秒重新绘制一次。
最重要的是,我在Developers菜单中启用了实际设备上的“Show layout updates”选项。它显示了更有趣的观点 - 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()
});
}
答案 0 :(得分:1)
我无法显示很多代码,但我会做标准片段附件 然后在具有特定睡眠周期的片段中创建一个线程 然后在ui-thread上更新搜索栏进度。
尝试使用Handler
更新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
的方法。这是您的实际代码吗?
答案 1 :(得分:1)
问题是TextView宽度设置为wrap_content,因此每次更新值时都会重绘它。问题是如果重新绘制子元素,即TextView,那么所有父视图也将强制重绘。
基本上,将动态视图设置为特定大小或match_parent。
答案 2 :(得分:0)
我想我看到它正在做什么,通过使用android:layout_above
您的顶部片段是在底部之后绘制的。所以它受到更新的底部影响。
使用android:layout_alignParentTop="true"
可以防止这种情况发生。
如果你还没有看到它,你一定要查看I/O talk about custom views。 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>