2012-03-18 51 views
0

我有以下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

什麼是空? llParent或調用findViewById()的結果? – 2012-03-18 22:06:06

回答

3

在我看來,你想要的是一個監聽器或委託方法的概括,當ListView的AsyncTask達到onPostExecute時,您的自定義ListView可以調用它。這將使您的自定義組件可重複使用(例如,如果您使用它與一個ProgressBar具有不同ID的另一個看法是什麼?)

我將創建一個內部接口(com.example.ListView.AsyncTaskCompletionListener或類似)有一個方法(onAsyncTaskComplete例如),給這個類型的實例變量com.example.ListView,讓Activity實現接口和方法。

在您的自定義ListView的AsyncTask的onPostExecute中,查看偵聽器實例變量是否爲空,然後調用其上的接口方法。

當您在活動中設置ListView時,將ListView的偵聽器實例變量設置爲活動(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); 
    } 
} 
+0

您的建議很有效,我覺得這是對我的問題非常乾淨的方法。非常感謝你! – 2012-03-19 09:37:25

+0

不客氣。很高興我能幫上忙! – 2012-03-19 11:08:38

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,和「_」。

+0

不知道我怎麼能直接訪問進度條。 這個線程的重點是如何訪問孩子的父項。 謝謝 – 2012-03-19 09:38:27

1

首先,聽起來像你真正想要的是ListFragment。無論您選擇哪種方式,只需在ListView中爲ProgressBar提供一個setter,然後在onCreate()中傳遞它。然後,你可以乾淨地直接訪問你的ListView中的ProgressBar(雖然總是檢查一個null)。

+0

使用Android 2.2,不允許使用ListFragment。 我不確定我瞭解你的建議。 謝謝 – 2012-03-19 09:22:30

+0

就像接受的答案一樣,但不是提供一個監聽器(這也是一個好方法),而是爲列表的「進度條」提供一個setter:'customListView.setProgressBar(theProgressBar);'。 – dmon 2012-03-19 14:05:57