Изменение макета RecyclerView при изменении ориентации работает только в первом представлении - PullRequest
0 голосов
/ 19 января 2019

В моем приложении у меня есть этот код для расчета размера телефона и изменения RecyclerView диспетчера макета на GridLayoutManager или LinearLayoutManager

private void changeFeedsLayout() {
    // Choose between one, two or three elements per row
    if (dpWidth > 720 && getResources().getConfiguration().orientation ==
            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
        instagram_feeds.setLayoutManager(new GridLayoutManager(
                context, 3, LinearLayoutManager.VERTICAL, false));
    } else if (dpWidth > 520) {
        instagram_feeds.setLayoutManager(new GridLayoutManager(
                context, 2, LinearLayoutManager.VERTICAL, false));
    } else {
        instagram_feeds.setLayoutManager(new LinearLayoutManager(
                context, LinearLayoutManager.VERTICAL, false));
    }
}

этот код работает нормально, когда я присоединяю или фиксирую каждый фрагмент кконтейнер на MainActivity, но он не работает при изменении ориентации телефона, для решения этой проблемы я использую этот код:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    changeFeedsLayout();
}

и, к сожалению, макет менеджера RecyclerView всегда равен LinearLayoutManagerи я не могу решить это.после включения другого фрагмента и возврата к предыдущему фрагменту работает нормально.

ОБНОВЛЕНИЕ

при изменении ориентации телефона этот код как:

instagram_feeds.setLayoutManager(new LinearLayoutManager(
                    context, LinearLayoutManager.VERTICAL, false));

donне работает с изменением ориентации телефона по методу changeFeedsLayout(), и этот метод не может правильно рассчитать размер телефона при изменении ориентации телефона

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Это может звучать странно, но единственное правильное решение для этого случая - поместить эти настройки в ресурсы.ОС Android собирает ресурсы на основе множества свойств, и одно из них имеет наименьшую ширину.Чтобы отделить список от сетки: values ​​/ bools.xml :

<resources>
    <bool name="is_grid">false</bool>
</resources>

, другой будет values-sw520dp / bools.xml :

<resources>
    <bool name="is_grid">true</bool>
</resources>

Для числа столбцов одинаковая логика values-sw520dp / inteers.xml :

<resources>
    <integer name="grid_column_count">2</integer>
</resources>

И values-sw720dp / inteers.xml :

<resources>
    <integer name="grid_column_count">3</integer>
</resources>

Таким образом, в коде это будет что-то вроде:

if (getResources().getBoolean(R.bool.is_grid)) {
    instagram_feeds.setLayoutManager(new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.grid_column_count));
} else {
    instagram_feeds.setLayoutManager(new LinearLayoutManager(getActivity());
}

Это должно применяться всякий раз, когда вы создаете свое представление, не нужно обрабатывать изменения конфигурации - это уже сделано для вас.Дай ОС сделать свою работу.

0 голосов
/ 04 февраля 2019

GridLayoutManager.LayoutParams объясняется в его комментариях:

if the orientation is VERTICAL, the width parameter is ignored and

if the orientation is HORIZONTAL, the height parameter is ignored

because child view is expected to fill all of the space given to it.

смысл:

, что LinearLayoutManager всегда будет иметь один столбец;

в то время какGridLayoutManager «может» иметь 1 (или более) столбцов.

0 голосов
/ 04 февраля 2019

Чтобы справиться с изменением ориентации и работать соответственно, я сделал следующее:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        Log.i("SCREEN DP","Orientation:"+ getResources().getConfiguration().orientation +" Width = "+getWidthDp());
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.i("SCREEN DP","Orientation:"+ newConfig.orientation +" Width = "+getWidthDp());
    }

    public float getWidthDp(){
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        return displayMetrics.widthPixels / displayMetrics.density;
    }
}

Логи показывают:

I/SCREEN DP: Orientation:1 Width = 411.42856
I/SCREEN DP: Orientation:2 Width = 683.4286
I/SCREEN DP: Orientation:1 Width = 411.42856
I/SCREEN DP: Orientation:2 Width = 683.4286

Не забудьте добавить android:screenOrientation="fullSensor" в Манифест, чтобы иметь возможность обрабатывать все ориентации.

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