34

リストにカスタムヘッダーを設定するのに問題があります。

カスタムアダプタを使用してListFragmentを作成しています。リストは正常に機能していますが、フラグメントのライフサイクルのどこにヘッダーをアタッチするかを把握しようとしています。

アダプターを設定する前に、ヘッダーを追加する必要があることはわかっています。

onActivityCreatedにヘッダーを追加しようとしましたが、フラグメントがバックスタックから戻るたびに呼び出され、アダプターもonActivityCreatedに設定したため、失敗します。

onCreateに追加しようとしましたが、ライフサイクルのその段階ではビュー階層を使用できません。

onCreateViewに追加しようとしましたが、膨張から返されたビューをListViewにキャストできませんでした。そのため、ヘッダーをバニラビューに追加できませんでした。

何かご意見は?

4

7 に答える 7

34

あなたがあなたの問題を解決したかどうかはわかりませんが、ここに私のために働いた解決策があります:

に電話をかけないListFragment.setListAdapter()でくださいListFragment.onCreate()。次のように、ヘッダー ビューを保持できるフィールド変数があることを確認してください。

View mheaderView;

次にListFragment.onCreateView()、ヘッダー View をインフレートし、次のように変数に割り当てます。

View list_root = inflater.inflate(R.layout.fragment_list, null);
// Get the list header - to be added later in the lifecycle
// during onActivityCreated()
mheaderView = inflater.inflate(R.layout.list_header, null);
return list_root;

最後に、 をListFragment.onActivityCreated() 呼び出すことができますListFragment.getListView().addHeaderView()。基本的には次のようなものです:

super.onActivityCreated(savedInstanceState);
if (mheaderView != null)  this.getListView().addHeaderView(headerView);
// Don't forget to now call setListAdapter()
this.setListAdapter(listAdapter);
于 2011-06-01T18:30:12.957 に答える
32

このソリューションは、画面の反転で機能します。

onActivityCreated() では:

getListView().addHeaderView(mHeaderView);
if (mMyAdapter == null) {
    mMyAdapter = new MyAdapter(getActivity(), null);
}
setListAdapter(mMyAdapter);

そして onDestroyView() で

setListAdapter(null);
于 2011-11-15T18:53:41.437 に答える
18

私の解決策:

public void onActivityCreated(Bundle savedInstanceState) {
    setListAdapter(null);
    getListView().addHeaderView(mHeader);
    setListAdapter(mAdapter);
}
于 2012-04-06T17:08:36.483 に答える
2

私のために働いた短い解決策として:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    View headerView = getActivity().getLayoutInflater().inflate(R.layout.header, null);
    getListView().addHeaderView(headerView);

    ArrayAdapter<XY> mAdapter = createAdapter(); // create here your own adapter
    setListAdapter(mAdapter);
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    setListAdapter(null);
}
于 2013-03-02T14:19:46.050 に答える
2

これは、リスト ビューでフッター/ヘッダーを処理するための私のソリューションです。保持フラグメントで使用します。アダプターは renderView() メソッドで初期化されます。このメソッドは必要な回数呼び出すことができ (ビュー内のデータを更新する場合など)、フッター/ヘッダーは正常に機能します。このコードを Android 2、3、4 でテストしました。

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);

    ...

    renderView();
}


@Override
public void onDestroyView()
{
    super.onDestroyView();

    // free adapter
    setListAdapter(null);
}


private void renderView()
{
    // reference
    ListView listView = getListView();

    // adapter
    if(getListAdapter()==null)
    {
        // init adapter
        mAdapter = new MyAdapter(...);
    }
    else
    {
        // refill adapter
        // this method assign array list object to adapter and call notifyDataSetChanged()
        mAdapter.refill(...);
    }

    // add footer
    setListAdapter(null);
    if(listView.getFooterViewsCount()==0)
    {
        mFooterView = getActivity().getLayoutInflater().inflate(R.layout.my_footer, null);
        listView.addFooterView(mFooterView);
    }

    // set adapter
    setListAdapter(mAdapter);
}
于 2012-10-20T19:51:02.350 に答える
0

ヘッダー レイアウトの高さに問題があったため、次の解決策に従いました。

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setListAdapter(null);//avoid problems with orientation changes
    header = getActivity().getLayoutInflater().inflate(R.layout.row_diario_header,getListView(),false);
    getListView().addHeaderView(header);
    ArrayList<Notificacao> nots = new ArrayList<>();

    nots.add(new Notificacao("16/04/2015", "Test", "Erro"));
    setListAdapter(new DiarioAdapter(getActivity(), R.layout.listview_diario, nots));
}

Header は View のインスタンスで、DiarioAdapter はカスタム ArrayAdapter です。

更新 1

リストフラグメントの重複に問題がある場合は、FragmentTransaction ADD を REPLACE に変更してください。

于 2015-04-17T19:22:41.313 に答える
0

現在、クラスの拡張で次のソリューションを使用していますListFragment

1)クラスでonActivityCreated、アダプター(クラス変数)がnullかどうかを確認し、インスタンス化します。次に、フッターを次のようにインフレートします。

View footerView = View.inflate
    (getActivity(), R.layout.list_footer_loader_view, null);

これを行う必要があるのは 1 回だけです。footerView とアダプタは一度だけ作成する必要があります。私はこれらの両方を自分で作成しますonActivityCreated

ここで「難しい部分」に進み、onCreate でフラグメントを次のように設定します。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

onCreateアクティビティとは関係がないので、で行うのが好きです。画面setRetainInstance(true)の向きなどのイベントでアクティビティが破棄された後、フラグメントは再作成されません。

これらの行の後に、次のようにフッターを追加します。

getListView().addFooterView(footerView);

次に、アダプターをリストに接続します。

setListAdapter(adapter);

これは、アクティビティが終了するたびに実行する必要があります。これは で実行してくださいonActivityCreated

onCreateまた、フラグメントに関して一般的に考慮すべき重要な事項の 1 つは、アクティビティが呼び出されるたびにフラグメントを作成しないことです。

たとえば、次のようにします (サポート パッケージを使用していない場合)。

MyFragment myFragment  = (MyFragment)
    getFragmentManager().findFragmentByTag(tag);
if (myFragment == null) {
    myFragment = MyFragment.newInstance();
    getFragmentManager().beginTransaction().
            add(myFragment, tag).commit();
}

もちろん、タグがそのフラグメントに対して一意である場合、これはフラグメントを一度だけ作成します。

于 2013-02-15T19:07:45.760 に答える