1. ホーム
  2. アンドロイド

Androidレイアウトの各機種への適応を簡単に紹介(GridViewを含む)

2022-02-24 16:52:56
<パス

  最近の個人的なプロジェクトは終わりに近づいているのですが、別の問題が発生しました。解像度の異なる携帯電話では、以下のインターフェイスを例にとると、レイアウトが思った通りにならないことがよくあるのです。

  今のところ、インターフェースのレイアウトに問題はなく ただ、レイアウトファイルを書くときに、全部スマホの高さに合わせて書きました。 背の高い携帯に出会うと、こんな風に表示されるんです。

  ご想像の通り、スマホが短いとどうしても表示が不完全になってしまうので、ユーザーのスマホの高さに応じて各コントロールの高さを動的に調整する必要があるのです。

1. xml ファイルを解析する。

  The layout is generally a LinearLayout with a Banner at the top, then two consecutive TextViews + GridView, a Fragment interface, and a ViewPager+Fragment+RadioButton at the bottom to implement the bottom menu bar, which also occupies a certain height. For the implementation of the menu bar please see.

Android: ViewPager+Fragment+RadioButton implementation of the bottom menu bar sliding switch

Note: For the interface to adapt on different models, be sure to use the padding and margin attributes sparingly in the layout file, which can complicate the situation.   The initial xml file was filled with a lot of padding and margin, but later on, after modification, I only kept two margins, i.e. 5dp spacing above and below each of the two TextViews (personal faculty and data visualization).   Then the situation becomes clear: the
Screen height = Height of status bar above + Height of Banner + 5dp + 20dp of TextView + 5dp + GridView + 5dp + 20dp of TextView + 5dp + GridView + 50dp of a set of RadioButton. 2. Get the screen height. WindowManager manager = this.getWindowManager(); DisplayMetrics outMetrics = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(outMetrics); int width = outMetrics.widthPixels; int height = outMetrics.heightPixels; width = px2dip(this, width); //360dp height = px2dip(this, height); //720dp   Where the pixel px to dp method px2dip. public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); }   The final calculation is 720dp high and 360dp wide for the screen. 3. Get the height of the status bar above. public int getStatusBarHeight() { Resources resources = this.getResources(); int resourceId = resources.getIdentifier("status_bar_height","dimen","android"); int height = resources.getDimensionPixelSize(resourceId); return px2dip(this, height); //24dp }   The height of the top status bar is 24dp.
  So you end up with the following height in addition to the status bar and the RadioButton below. int pagerHeight = height - status_bar_height - 50;   We then write it to a SharedPreferences file at sharedPreferences = getSharedPreferences("user_info", Context.MODE_PRIVATE); editor = sharedPreferences.edit(); editor.putInt("pager", pagerHeight); editor.commit();   The final pager is where we put a Banner + two GridViews + two TextViews. 4. Dynamically generated height   In the QueryFragment's onCreateView method, we need to come to dynamically set the height, where I have set the height ratio of the topmost rotating image to the two GriViews below at 6:7:7, i.e. private void setHeight() { SharedPreferences sharedPreferences = getContext().getSharedPreferences("user_info", Context.MODE_PRIVATE); float pagerHeight = sharedPreferences.getInt("pager", StudentMainActivity.pagerHeight); pagerHeight -= 60; LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) banner.getLayoutParams(); linearParams.height = dip2px(getContext(), pagerHeight / 20 * 6); banner.setLayoutParams(linearParams); linearParams = (LinearLayout.LayoutParams) eduGridView.getLayoutParams(); linearParams.height = dip2px(getContext(), pagerHeight / 20 * 7); eduGridView.setLayoutParams(linearParams); linearParams = (LinearLayout.LayoutParams) visionGridView.getLayoutParams(); linearParams.height = dip2px(getContext(), pagerHeight / 20 * 7); visionGridView.setLayoutParams(linearParams); }   The subtracted 60dp is the height of the two TextViews and the four margins, but of course you can dynamically set the height of the two TextViews, but I'm limiting it to 20dp high. 5. GridView's Adapter file modification   The use of the GridView requires the Adapter file, in which we set each item, in this case, the item is an ImageView above and a TextView below. <?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:gravity="center_horizontal" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical" android:padding="0dp"> <ImageView android:id="@+id/iv_grid" android:layout_width="60dp" android:layout_height="79.375dp"/> <TextView android:id="@+id/tv_grid" android:layout_width="wrap_content" android:layout_height="20dp" android:layout_marginTop="3dp" android:gravity="center" android:text=""/> </LinearLayout> </LinearLayout>   So then in the adapter file we also have to dynamically set the height of each item, because each GridView has two rows, so the height of a GridView is height = (ImageView + 3dp's margin + TextView height) * 2   Here the height of the TextView is also like the previous one, I have written it to death at 20dp, while the height of the GridView has been calculated earlier as follows. float gridViewHeight = pagerHeight / 20 * 7;   So the final height of the ImageView is (gridViewHeight - 46) / 2   So we end up setting it up like this. @Override public View getView(int position, View convertView, ViewGroup parent) { View view = LayoutInflater.from(context).inflate(R.layout.item_grid, null); SharedPreferences sharedPreferences = context.getSharedPreferences("user_info", Context.MODE_PRIVATE); pagerHeight -= 60; float gridViewHeight = pagerHeight / 20 * 7; ImageView iv = view.findViewById(R.id.iv_grid); TextView tv = view.findViewById(R.id.tv_grid); LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) iv.getLayoutParams(); linearParams.height = dip2px(context, (gridViewHeight - 46) / 2); iv.setLayoutParams(linearParams); iv.setImageResource(images[position]); tv.setText(names[position]); return view; }   The core code is. LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) iv.getLayoutParams(); linearParams.height = dip2px(context, (gridViewHeight - 46) / 2); iv.setLayoutParams(linearParams);   Note here: LinearLayout.LayoutParams needs to be converted to pixels when setting the height, so it needs to use dip2px:. public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); }
Screen height = Height of status bar above + Height of Banner + 5dp + 20dp of TextView + 5dp + GridView + 5dp + 20dp of TextView + 5dp + GridView + 50dp of a set of RadioButton.