38

Внутри моего фрагмента я устанавливаю мой GridLayout следующим образом: mRecycler.setLayoutManager(new GridLayoutManager(rootView.getContext(), 2));Изменение числа столбцов с GridLayoutManager и RecyclerView

Итак, я просто хочу, чтобы изменить это 2 для 4 когда пользователь поворачивает телефон/таблетки. Я читал о onConfigurationChanged, и я попытался заставить его работать для моего дела, но это не так. Когда я поворачиваю свой телефон, приложение вылетает ...

Не могли бы вы рассказать мне, как решить эту проблему?

Вот мой подход, чтобы найти решение, которое не работает правильно:

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

     int orientation = newConfig.orientation; 

     if (orientation == Configuration.ORIENTATION_PORTRAIT) { 
      mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2)); 
     } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) { 
      mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4)); 
     } 
    } 

Спасибо заранее!

+0

, пожалуйста, добавьте журнал сбоев –

+0

Я только что посмотрел на свой логарифм, и это не вызвало краха. Но он все еще не работает. – fapps

+0

Я бы не создал нового менеджера, но вместо этого использовал существующий. Используйте getLayoutManager() в своем recyclerview, отбросите его в GridLayoutManager. На этом управляющем вызове setSpanCount (ориентация == портрет? 2: 4) И ради перерисовки вызова вида adaper.notifyDatasetChanged() Это должно работать нормально, если ваше представление не перерисовывается каждый раз. –

ответ

51

Попробуйте обработки этого внутри onCreateView методы вместо, так как он будет называться каждый раз, когда есть изменение ориентации:

if(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){ 
    mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2)); 
} 
else{ 
    mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4)); 
} 
+0

Я попробую и расскажу. Благодаря! – fapps

+0

Спасибо! Это здорово! – fapps

+2

Правильное ли поведение этой задачи? Спасибо – ciccioska

55

Если у вас есть более чем одно условие или использовать значение в нескольких местах, это может выйти из рука довольно быстро. Я предлагаю создать следующую структуру:

res 
    - values 
    - dimens.xml 
    - values-land 
    - dimens.xml 

с res/values/dimens.xml существа:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <integer name="gallery_columns">2</integer> 
</resources> 

и res/values-land/dimens.xml существо:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <integer name="gallery_columns">4</integer> 
</resources> 

А код становится (и навсегда останется), как это:

final int columns = getResources().getInteger(R.integer.gallery_columns); 
mRecycler.setLayoutManager(new GridLayoutManager(mContext, columns)); 

Вы можете легко увидеть, как легко добавлять новые способы определения количества столбцов, например, используя -w500dp/-w600dp/-w700dp папки ресурсов вместо -land.

Это также довольно легко сгруппировать эти папки в отдельную папку ресурсов в случае, если вы не хотите загромождать ваши другие (более релевантные) ресурсы:

android { 
    sourceSets.main.res.srcDir 'src/main/res-overrides' // add alongside src/main/res 
} 
6

Рециркулирующий View поддерживает AutofitRecycleView.

Вам необходимо добавить android:numColumns="auto_fit" в свой XML-файл.

Вы можете обратиться к этой AutofitRecycleViewLink

+0

Отличная реализация! вращайте экран, чтобы динамически изменять количество столбцов и сохраняйте положение прокрутки. –

+0

Это, вероятно, самое совершенное решение, но если ваш дизайнер не решит что-то другое. Иногда дизайн просто заставляет нас реализовать на жестком пути – Sniper

0

Вы можете реализовать метод в вашем recyclerView onMeasure. Во-первых, создать класс Java AutofitRecyclerView

public class AutofitRecyclerView extends RecyclerView { 
//private GridLayoutManager manager; 
private StaggeredGridLayoutManager manager; 
private int columnWidth = -1; 

public AutofitRecyclerView(Context context) { 
    super(context); 
    init(context, null); 
} 

public AutofitRecyclerView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(context, attrs); 
} 

public AutofitRecyclerView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(context, attrs); 
} 

private void init(Context context, AttributeSet attrs) { 
    if (attrs != null) { 
     int[] attrsArray = { 
       android.R.attr.columnWidth 
     }; 
     TypedArray array = context.obtainStyledAttributes(attrs, attrsArray); 
     columnWidth = array.getDimensionPixelSize(0, -1); 
     array.recycle(); 
    } 

    manager = new StaggeredGridLayoutManager(1, GridLayoutManager.VERTICAL); 
    setLayoutManager(manager); 

} 

@Override 
protected void onMeasure(int widthSpec, int heightSpec) { 
    super.onMeasure(widthSpec, heightSpec); 
    if (columnWidth > 0) { 
     int spanCount = Math.max(1, getMeasuredWidth()/columnWidth); 
     manager.setSpanCount(spanCount); 
    } 
}} 

В вашем XLM файл макета activity_main.xml

<yourpackagename.AutofitRecyclerView 
      android:id="@+id/recycler_view" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:columnWidth="@dimen/column_width" 
      android:clipToPadding="false"/> 

Затем установите переменную ширину каждого элемента в размере файла значений папок значения/Dimens.XML

<resources> 
    <dimen name="column_width">250dp</dimen> 
</resources> 

Это может быть для разных разрешений экрана значения-xxhdpi/dimens.xml

<resources> 
<dimen name="column_width">280dp</dimen> 
</resources> 

В вашей деятельности в OnCreate месте событий следующий код

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
    recyclerView.addItemDecoration(new MarginDecoration(this)); 
    recyclerView.setHasFixedSize(true); 
    recyclerView.setAdapter(new NumberedAdapter(50)); 
} 
1

В OnCreate() событие вы можете использовать StaggeredGridLayoutManager

mRecyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);  

mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(
     1, //number of grid columns 
     GridLayoutManager.VERTICAL);  

mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); 

Затем, когда пользователь поворачивает захват экрана события, и изменить количество колонок автоматически

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    if (getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {   
      mStaggeredGridLayoutManager.setSpanCount(1); 

    } else {   
      //show in two columns 
      mStaggeredGridLayoutManager.setSpanCount(2);   
    } 
} 
4

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

public static int calculateNoOfColumns(Context context) { 
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 
    float dpWidth = displayMetrics.widthPixels/displayMetrics.density; 
    int scalingFactor = 200; // You can vary the value held by the scalingFactor 
    // variable. The smaller it is the more no. of columns you can display, and the 
    // larger the value the less no. of columns will be calculated. It is the scaling 
    // factor to tweak to your needs. 
    int columnCount = (int) (dpWidth/scalingFactor); 
    return (columnCount>=2?columnCount:2); // if column no. is less than 2, we still display 2 columns 
} 

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

NB: Вы можете изменять значения, содержащиеся в scalingFactor переменным. Чем меньше, тем больше нет. столбцов, которые вы можете отобразить, и чем больше значение, тем меньше нет. столбцов. Это фактор масштабирования для настройки ваших потребностей.

0

Я закончил работу с этим методом onCreate.

private RecyclerView recyclerView = null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
    recyclerView.setHasFixedSize(true); 
    Configuration orientation = new Configuration(); 
    if(this.recyclerView.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
     recyclerView.setLayoutManager(new GridLayoutManager(this, 2)); 
    } else if (this.recyclerView.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 
     recyclerView.setLayoutManager(new GridLayoutManager(this, 4)); 
    } 
      connectGetApiData(); 
} 

Это идеальное решение для моего приложения.

Смежные вопросы