【问题标题】:Android GridVIew Change number of columns depending on OrientationAndroid GridVIew 根据方向更改列数
【发布时间】:2012-10-07 07:13:30
【问题描述】:

我想以网格的形式显示6张图片,如下所示。

纵向、2 列、3 行和 在景观方向 3 列,2 行

通过使用 Android GridView 并在 layout-port 和 layout-land 目录中定义不同的网格布局,我能够实现这种效果。

后来根据我的活动要求,我在 manifest.xml 中添加了一个参数,即

android:configChanges = "mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize"`

一旦屏幕方向发生变化,停止我的活动以重新创建。

添加此参数后,我的网格视图未按预期方式运行。有时显示 1 列,有时显示 2 列,有时显示 3 列。

根据设备的方向,我将 gridView.setNumberOfColumns(2)gridView.setNumberOfColumns(3) 方法放在我的网格适配器的 get view 方法中。

请帮我在不去掉Manifest.xml中android:configChanges参数的情况下实现这个效果

【问题讨论】:

    标签: android android-layout gridview


    【解决方案1】:

    使用强大的资源系统。

    在 xml 布局中,将列数设置为整​​数资源,然后在 /values/integers.xml 中将其设置为 2(纵向),/values-land/integers.xml 将其设置为 3(横向)

    // 好吧,如果你在 manifest 中进行 configChanges,你将不得不在 onConfigurationChanged 中从 java 中更改列数

    【讨论】:

    • 谢谢伙计。现在是values-land 并且只有values 用于纵向模式,无论如何+1。
    • 我认为应该是values-landvalues-port(而不是纯粹的values),以便更好地与各种设备兼容。
    【解决方案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);
      

      【讨论】:

      • getDefaultDisplay().getWidth() 现在已弃用。有没有其他获取方式?
      【解决方案4】:

      我的解决方案:

      values/dimens.xml:

      <resources>
          <dimen name="grip_view_entry_size">160dp</dimen>
          <dimen name="grip_view_spacing">10dp</dimen>
      </resources>
      

      layout/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中的数据。

      将该活动节点的 android:configChanges="orientation" 放入清单中。

      【讨论】:

      • 你会得到异常,因为setContentView只能被调用一次。
      • 我不认为 setcontentview 只能被调用一次,而是该特定布局中的所有东西都必须通过 findViewById 用其中的东西重新初始化,它会顺利进行
      【解决方案6】:

      当您在清单中使用 android:configChanges = "orientation" 时,您的活动不会在方向更改时重新创建(横向到纵向,反之亦然)。如果您不想从清单中删除此标记,则必须覆盖 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;
        }
        

        【讨论】:

          【解决方案8】:

          这是 XML:

          <GridLayout
              android:id="@+id/gridLayout"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:columnCount="@integer/num_columns"
              android:rowCount="@integer/num_rows"
              android:orientation="vertical">
              <!-- TextViews, ImageViews, etc -->
          </GridLayout>
          

          然后在你的片段中:

          @BindView(R.id.gridLayout) GridLayout gridLayout;
          
          @Override
          public void onConfigurationChanged(Configuration newConfig) {
              super.onConfigurationChanged(newConfig);
              final ArrayList<View> views = new ArrayList<>();
              for (int i = 0; i < gridLayout.getChildCount(); i++) {
                  views.add(gridLayout.getChildAt(i));
              }
              gridLayout.removeAllViews();
              gridLayout.setColumnCount(getContext().getResources().getInteger(R.integer.num_columns));
              gridLayout.setRowCount(getContext().getResources().getInteger(R.integer.num_rows));
              for (int i = 0; i < views.size(); i++) {
                  views.get(i).setLayoutParams(new GridLayout.LayoutParams());
                  gridLayout.addView(views.get(i));
              }
          }
          

          【讨论】:

            【解决方案9】:

            将此代码添加到 onCreate

             gridView_menu.setNumColumns(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? 3:4);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-09-16
              • 2012-02-09
              • 1970-01-01
              相关资源
              最近更新 更多