Android GridVIew Изменение количества столбцов в зависимости от ориентации
Я хочу отобразить 6 изображений в виде сетки следующим образом.
в портретной ориентации, 2 coumns, 3 ряда и
в ориентации на ландшафт 3 столбца, 2 строки
Используя Android GridView и определяя различные макеты сетки в каталогах макета-порта и макета-земли, я смог добиться этого эффекта.
Позже в соответствии с моим требованием к работе я добавил один параметр в manifest.xml, который
android:configChanges = "mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize"`
чтобы остановить мою активность, чтобы воссоздать после изменения ориентации экрана.
После добавления этого параметра мой вид сетки не ведет себя ожидаемым образом. Он иногда показывает 1 столбец, иногда 2 столбца, а иногда и 3 столбца.
Я размещаю методы gridView.setNumberOfColumns(2)
или gridView.setNumberOfColumns(3)
в методе получения моего адаптера сетки в зависимости от ориентации устройства.
Пожалуйста, помогите мне достичь этого эффекта, не удалив параметр android:configChanges
в Manifest.xml
Ответы
Ответ 1
Используйте мощную систему ресурсов.
В макете xml задайте количество столбцов для целочисленного ресурса, а затем в /values/integers.xml
установите для него значение 2 для портрета и в /values-land/integers.xml
установите для него значение 3 для пейзажа
//хорошо, если вы выполните configChanges в манифесте, вам придется изменить количество столбцов из java в onConfogurationChanged
Ответ 2
@Override
public void onConfigurationChanged(Configuration newConfig) {
grid.setNumColumns(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ? 3 : 2);
super.onConfigurationChanged(newConfig);
}
Ответ 3
вы можете установить число столбцов программно, используя
float scalefactor = getResources().getDisplayMetrics().density * 100;
int number = getWindowManager().getDefaultDisplay().getWidth();
int columns = (int) ((float) number / (float) scalefactor);
gridView.setNumColumns(columns);
Ответ 4
Мое решение:
значения /dimens.xml:
<resources>
<dimen name="grip_view_entry_size">160dp</dimen>
<dimen name="grip_view_spacing">10dp</dimen>
</resources>
макет /gridview.xml
<GridView android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:numColumns="auto_fit"
android:verticalSpacing="@dimen/grip_view_spacing"
android:horizontalSpacing="@dimen/grip_view_spacing"
android:stretchMode="columnWidth"
android:gravity="center"
android:scrollingCache="false"
android:fastScrollEnabled="true"
android:animationCache="false"/>
в вашем фрагменте:
private void refreshGridView() {
int gridViewEntrySize = getResources().getDimensionPixelSize(R.dimen.grip_view_entry_size);
int gridViewSpacing = getResources().getDimensionPixelSize(R.dimen.grip_view_spacing);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int numColumns = (display.getWidth() - gridViewSpacing) / (gridViewEntrySize + gridViewSpacing);
gridView.setNumColumns(numColumns);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
refreshGridView();
}
@Override
public void onResume() {
super.onResume();
refreshGridView();
}
Ответ 5
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
setContentView(R.layout.lay_vertical);
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.lay_horizontal);
}
};
Затем снова загрузите данные в gridview в соответствии с вашими потребностями.
Поместите андроид: configChanges = "ориентация" для этой активности node в манифесте.
Ответ 6
Пока вы используете android: configChanges = "ориентация" в манифесте, ваша активность не воссоздается при изменении ориентации ( "Пейзаж для портрета" или наоборот). Если вы не хотите удалять этот тег из манифеста, вам необходимо переопределить onConfigchanged и поместить туда некоторую логику кода.
Ответ 7
я сделал его на основе размера экрана, но не dpi
public static int getGridColumnsCount(Context context){
boolean landscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
float hi=displayMetrics.heightPixels/displayMetrics.xdpi;
float wi=displayMetrics.widthPixels/displayMetrics.ydpi;
float screenWidthInch = landscape ? Math.max(wi, hi) : Math.min(wi, hi);
float screenWidthCm = screenWidthInch * 2.54f;
int columns = (int)(screenWidthCm/2);
return columns < 3 ? 3 : columns;
}