赞
踩
给项目进行平板的适配。找到平板运行了一下,看看效果,基本问题不大。只是对于首页的GridView显示的列数需要改一下。原先我是使用android:numColumns="3",一行显示3列。那么运行在了平板上就显得间隔太大,所以我准备显示4列。
那么我立马想到的是使用:
android:numColumns="auto_fit"
android:columnWidth="120dp"
大家都清楚这是设置GridView列宽并尽可能的填满可用空间。会随着屏幕的大小自动调节列数的。
运行在了手机与平板上以后,手机显示3列正常,两个平板,一个4列,一个5列。
无语了。。明明两个平板基本一样大啊!只是分辨率不同。一个1080*1920,一个1200*1920。
那么没办法,只有查看一下GridView源码,看看auto_fit怎么实现的。
找了一会发现了determineColumns方法,就如名字一样“确定列数”
- private boolean determineColumns(int availableSpace) {
- final int requestedHorizontalSpacing = mRequestedHorizontalSpacing;
- final int stretchMode = mStretchMode;
- final int requestedColumnWidth = mRequestedColumnWidth;
- boolean didNotInitiallyFit = false;
-
- if (mRequestedNumColumns == AUTO_FIT) {
- if (requestedColumnWidth > 0) {
- // Client told us to pick the number of columns
- mNumColumns = (availableSpace + requestedHorizontalSpacing) /
- (requestedColumnWidth + requestedHorizontalSpacing);
- } else {
- // Just make up a number if we don't have enough info
- mNumColumns = 2;
- }
- } else {
- // We picked the columns
- mNumColumns = mRequestedNumColumns;
- }
-
- if (mNumColumns <= 0) {
- mNumColumns = 1;
- }
追踪availableSpace
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // Sets up mListPadding
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- int heightMode = MeasureSpec.getMode(heightMeasureSpec);
- int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-
- if (widthMode == MeasureSpec.UNSPECIFIED) {
- if (mColumnWidth > 0) {
- widthSize = mColumnWidth + mListPadding.left + mListPadding.right;
- } else {
- widthSize = mListPadding.left + mListPadding.right;
- }
- widthSize += getVerticalScrollbarWidth();
- }
-
- int childWidth = widthSize - mListPadding.left - mListPadding.right;
- boolean didNotInitiallyFit = determineColumns(childWidth);
追踪requestColumnWidth
- /**
- * Set the width of columns in the grid.
- *
- * @param columnWidth The column width, in pixels.
- *
- * @attr ref android.R.styleable#GridView_columnWidth
- */
- public void setColumnWidth(int columnWidth) {
- if (columnWidth != mRequestedColumnWidth) {
- mRequestedColumnWidth = columnWidth;
- requestLayoutIfNecessary();
- }
- }
- int columnWidth = a.getDimensionPixelOffset(R.styleable.GridView_columnWidth, -1);
- if (columnWidth > 0) {
- setColumnWidth(columnWidth);
- }
dp转化为px这个工具方法大家一定没有少用,如下:
- /**
- * * 将dip或dp值转换为px值,保证尺寸大小不变 * * @param dipValue * @param scale *
- * (DisplayMetrics类中属性density) * @return
- */
- public static int dip2px(Context context, float dipValue) {
- final float scale = context.getResources().getDisplayMetrics().density;
- return (int) (dipValue * scale + 0.5f);
- }
- /**
- * The logical density of the display. This is a scaling factor for the
- * Density Independent Pixel unit, where one DIP is one pixel on an
- * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen),
- * providing the baseline of the system's display. Thus on a 160dpi screen
- * this density value will be 1; on a 120 dpi screen it would be .75; etc.
- *
- * <p>This value does not exactly follow the real screen size (as given by
- * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
- * the overall UI in steps based on gross changes in the display dpi. For
- * example, a 240x320 screen will have a density of 1 even if its width is
- * 1.8", 1.3", etc. However, if the screen resolution is increased to
- * 320x480 but the screen size remained 1.5"x2" then the density would be
- * increased (probably to 1.5).
- *
- * @see #DENSITY_DEFAULT
- */
- public float density;
总结一下:px与dp之间的倍数就是density,而density的值由分辨率和屏幕尺寸决定。
之后我打Log看看手机和平板的density。
那么手机(分辨率1920*1080)是2.75,屏幕宽1080/2.75=393dp(3列)
平板1号(分辨率1920*1200)是2,屏幕宽1200/2=600dp (5列)
平板2号(分辨率1920*1080)是2,屏幕宽1080/2=540dp (4列)
还记得我columnWidth设置的是多少?120dp
真是无语了600/120=5列,这个平板的分辨率我也是醉了。安卓的碎片化。。
那么找到了原因,也就好修改了,我通过计算屏幕宽的dp,如果大于480dp就设置4列。
其实解决这个适配需求还有许多好的方法。
分享出来,仅供参考。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。