Как получить доступ к элементу Layout у родителя от child? - PullRequest
0 голосов
/ 19 марта 2012

У меня есть следующий родительский 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) пуста ... есть ли шансы, что я смогу преодолеть эту проблему?

Спасибо, Фелипе

Ответы [ 3 ]

3 голосов
/ 19 марта 2012

Мне кажется, что обобщение того, что вы хотите, - это метод слушателя или делегата, который ваш пользовательский ListView может вызывать, когда AsyncTask ListView достигает onPostExecute. Это сделает ваш пользовательский компонент многократно используемым (например, что если вы используете его в другом представлении с ProgressBar, имеющим другой идентификатор?)

Я бы создал внутренний интерфейс (com.example.ListView.AsyncTaskCompletionListener или что-то подобное) с одним методом (например, onAsyncTaskComplete), дал бы com.example.ListView переменную экземпляра этого типа, и чтобы Activity реализовал интерфейс и способ.

В onPostExecute вашего пользовательского ListView AsyncTask проверьте, что переменная экземпляра слушателя не равна нулю, а затем вызовите метод интерфейса для нее.

Когда вы настраиваете ListView в Activity, устанавливаете переменную экземпляра слушателя 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 голос
/ 19 марта 2012

Прежде всего, звучит так, как будто вы действительно хотите ListFragment. Независимо от того, какой путь вы выберете, просто предоставьте установщик для ProgressBar в ListView и передайте его в onCreate(). Затем вы можете напрямую получить прямой доступ к ProgressBar в вашем ListView (хотя всегда проверяйте его на ноль).

0 голосов
/ 19 марта 2012

Попробуйте просто дать вашему индикатору выполнения собственный идентификатор и получить к нему доступ напрямую, не пытаясь пройти через его родительский элемент. Также внутренняя 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" />
...

Также попробуйте назвать свой идентификатор ресурса, используя только строчные буквы, цифры и '_'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...