Как отключить DialogFragment для изменения размера после отображения диалогового окна?

Я использую просмотр списка в DialogFragment, содержащийся в LinearLayout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/dialog_main_margin" >

<com.modelmakertools.simplemind.DragSortListView
    android:id="@+id/drag_list_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</LinearLayout>

где DragSortListView основан на стороннем потомке ListView, который позволяет переставлять элементы с помощью изображения перетаскивания.

Все работает нормально, когда этот код используется в (полноэкранном) действии, но при использовании в android.support.v4.app.DialogFragment перетаскивание элемента приводит к тому, что комбинация dialog + listview постоянно обновляет размер диалога. Это вызывает очень медленное перетаскивание, и я вижу много сообщений LogCat:

06-06 15:37:07.833: I/Choreographer(17281): Skipped 166 frames!  The application may be doing too much work on its main thread.

Чтобы определить источник проблемы, я изменил ширину и высоту просмотра списка на фиксированное значение 400dp (вместо match_parent / wrap_content). Исправление размера полностью устраняет проблему. Отсюда мой вопрос: есть ли способ избежать фрагмента диалога, чтобы изменить его размер, как только он был выложен один раз?

2 ответа

Я нашел способ остановить просмотр списка, обновляя размер диалога с помощью кода ниже. Однако, оказывается, это только решает часть проблемы: пока список не "зациклен", загрузка все еще очень медленная. Но у этого есть другая причина, которая выходит за рамки этого вопроса / ответа

@Override
public void onResume() {
    super.onResume();
    // Fixate the listview height once the listview has been measured rather than keeping it at "wrap_content"
    // This drastically improves rearrange performance.
    if (_listView != null) {
        _listView.postDelayed(new Runnable() {
            @Override
            public void run() {
                fixateListViewHeight();
            }
        }, 500);
    }
}

private void fixateListViewHeight() {
    if (_listView != null) {
        int h = _listView.getMeasuredHeight();
        if (h != 0) {
            LayoutParams params = (LayoutParams) _listView.getLayoutParams();
            if (params != null)
                params.height = h;
        }
    }
}

Попробуйте установить windowSoftInputMode собственность на adjustNothing в AndroidManifest.xml из действий, которые используют фрагмент диалога.

<activity
    ...
    android:windowSoftInputMode="adjustNothing">
...
Другие вопросы по тегам