我有以下父xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_places_linearLayout" >
<LinearLayout
android:id="@+id/loadingPanel"
style="@style/GenericProgressBackground" >
<ProgressBar style="@style/GenericProgressIndicator" />
</LinearLayout>
<com.example.ListView
android:id="@+id/bottomactionbar"
style="@style/BottomActionBar" />
</LinearLayout>
com.example.ListView是我的自定义组件,包含AsyncTask。完成此任务后,我想将父级的ProgressBar可见性设置为GONE。
因此,当子组件中的AsyncTask完成时,我尝试以下操作:
LinearLayout llParent = (LinearLayout)getParent();
((LinearLayout)llParent.findViewById(R.id.loadingPanel)).setVisibility(View.GONE);
不幸的是,llParent.findViewById(R.id.loadingPanel)行是空的......我有什么机会可以克服这个问题?
谢谢, 菲利普
答案 0 :(得分:3)
在我看来,当ListView的AsyncTask到达onPostExecute
时,你想要的是一个自定义ListView可以调用的侦听器或委托方法。这会使您的自定义组件可重复使用(例如,如果您在具有不同ID的ProgressBar
的其他视图上使用它,该怎么办?)
我会使用单个方法(例如com.example.ListView.AsyncTaskCompletionListener
)创建一个内部接口(onAsyncTaskComplete
或其他),给com.example.ListView
一个该类型的实例变量,并拥有Activity实现了接口和方法。
在自定义ListView的AsyncTask的onPostExecute
中,检查侦听器实例变量是否为null,然后在其上调用接口方法。
在Activity中设置ListView时,将ListView的侦听器实例变量设置为Activity(myListView.setAsyncTaskCompletionListener(this);
)的实例,并在侦听器方法中,将ProgressBar可见性设置为GONE。
ListView片段:
package com.example;
public class ListView extends android.widget.ListView {
private AsyncTaskCompletionListener listener;
public AsyncTaskCompletionListener getAsyncTaskCompletionListener() {
return listener;
}
public void setAsyncTaskCompletionListener(AsyncTaskCompletionListener atcl) {
listener = atcl;
}
...
public interface AsyncTaskCompletionListener {
public void onAsyncTaskComplete();
}
private MyAsyncTask extends AsyncTask<Void,Void,Void> {
...
protected void onPostExecute(Void result) {
if (listener != null) {
listener.onAsyncTaskComplete();
}
}
}
}
您的活动摘要:
public MyActivity extends android.app.Activity implements com.example.ListView.AsyncTaskCompletionListener {
com.example.ListView customListView;
ProgressBar progressBar;
...
public void onCreate(Bundle savedInstanceState) { // Could be onResume or somewhere else
...
progressBar = (ProgressBar)findViewById(R.id.progress_horizontal);
customListView = (com.example.ListView)findViewById(R.id.bottomactionbar);
customListView.setAsyncTaskCompletionListener(this);
}
...
public void onAsyncTaskComplete() {
progressBar.setVisibility(View.GONE);
}
}
答案 1 :(得分:1)
首先,听起来像你真正想要的是ListFragment
。无论您选择哪种方式,只需在ListView中为ProgressBar提供一个setter,并在onCreate()
中传递它。然后,您可以干净地直接访问ListView中的ProgressBar
(但总是检查null)。
答案 2 :(得分:0)
尝试只为您的进度条提供自己的ID,并直接访问它而不尝试通过其父级。此外,内部LinearLayout“loadingPanel”是不必要的。只需将进度条弹出到外部列表即可。这是一个XML布局的片段,包括SDK示例中的进度条:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar android:id="@+id/progress_horizontal"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="200dip"
android:layout_height="wrap_content"
android:max="100"
android:progress="50"
android:secondaryProgress="75" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/progressbar_1_default_progress" />
...
另外,请尝试仅使用小写字母,数字和“_”来命名资源ID。