Android开发之屏幕匹配的GridView

来源:互联网 发布:数据库功能节点 编辑:程序博客网 时间:2024/05/16 06:41

1、效果预览

         

左边为小米2s的效果,右边为模拟器的效果


2、屏幕适配的几个关键点

1、GridView的间距设置
2、Item项的间距设置
3、图片的尺寸设置

可以看见,每一项的间距有两部分组成:1、与父容器的间距。2、与其他Item的间距。与父容器的间距可以在xml文件中通过属性:layout_margin来指定,与其他Item的间距可以通过属性: horizontalSpacing来指定。并且要保持这两个的值相等,以达到相同间距的效果。图片的尺寸设置可以通过两种方式:第一种:ImageView的大小固定,设置Bitmap的尺寸。第二种:Bitmap的大小固定,设置ImageView的尺寸。这里用第二种方式举例说明。


3、在GridView的布局文件中:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#ececec"    android:orientation="vertical" >    <GridView         android:id="@+id/gridView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_margin="10dp"        android:verticalSpacing="15dp"        android:horizontalSpacing="10dp"        android:cacheColorHint="#00000000"        android:listSelector="@android:color/transparent"        android:stretchMode="columnWidth"        android:numColumns="2"        android:scrollbars="none"        /></LinearLayout>


可以看见:layout_margin与horizontalSpacing的值是相等的,这儿都给的10dp。除了这两处相等,后面还有一个值必须和这儿相等,后面会介绍。


4、Item的布局文件:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="match_parent"    android:orientation="vertical" >        <ImageView         android:id="@+id/iv_dog"        android:layout_width="200dp"        android:layout_height="150dp"        android:src="@drawable/dog"        android:scaleType="centerInside"        />    <RelativeLayout         android:id="@+id/relativeLayout"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        >        <LinearLayout             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:orientation="horizontal"            android:layout_marginLeft="5dp"            >            <ImageView                 android:layout_width="20dp"                android:layout_height="20dp"                android:src="@drawable/zan"                android:scaleType="centerInside"                />            <TextView                 android:layout_width="wrap_content"                android:layout_height="match_parent"                android:gravity="center_vertical"                android:layout_marginLeft="5dp"                android:text="123"                android:textColor="@color/gray"                android:textSize="10sp"                />        </LinearLayout>                <LinearLayout             android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:orientation="horizontal"            android:layout_alignParentRight="true"            android:layout_marginRight="5dp"            >            <ImageView                 android:layout_width="20dp"                android:layout_height="20dp"                android:src="@drawable/comment"                android:scaleType="centerInside"                />            <TextView                 android:layout_width="wrap_content"                android:layout_height="match_parent"                android:gravity="center_vertical"                android:layout_marginLeft="5dp"                android:text="123"                android:textColor="@color/gray"                android:textSize="10sp"                />        </LinearLayout>    </RelativeLayout></LinearLayout>

整个布局很简单,上面一个ImageView,下面一个RelativeLayout,并且在RelativeLayout中包含了左边的“点赞”和右边的“评论”布局。在这里,我将ImageView的layout_width与layout_height都给定了初始值200dp和150dp,其实这个没必要的,在后面的代码中会根据屏幕动态更改。这儿给了初始值只是为了更好的在eclipse中预览。因为我的图尺寸太大了。

5、代码控制

在MainActivity中非常简单,实例化GridView,再实例化一个MyAdapter,最后设置setAdapter方法就完了。
public class MainActivity extends Activity {    //控件    private GridView gridView = null;    private MyAdapter adapter = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 初始化布局        initialView();    }    /**     * 初始化布局     *      * @author chenchen 2014-11-20     */    private void initialView() {        gridView = (GridView) findViewById(R.id.gridView);        adapter = new MyAdapter(this);        gridView.setAdapter(adapter);    }}


重点是这个MyAdapter,接下来会重点讲解:

在MyAdapter中,有几个重要的成员变量要申明:
    private Activity context;        //图片的宽度    private int image_width = 0;    //图片的高度    private int image_height = 0;    //图片的宽高比例    private static float scale = 0.75f;     //偏移值    private static int offset = 10;            public MyAdapter(Activity context) {        this.context = context;                initialParams(context);    }

这儿有5个成员变量,context这儿不用多说大家都知道。image_width与image_height是图片的尺寸,是通过代码动态设置的。scale是宽高的比例,这个比例要根据图片的具体尺寸来确定。offset是偏移值,这个值必须和前面提到的layout_margin、horizontalSpacing的值相同,用来动态设置每一项的尺寸。
在构造函数中,调用了initialParams()方法,用来赋值这些成员变量。

    /**     * 初始化控件的参数     * @param context     * @author chenchen  2014-11-13     */    private void initialParams(Activity context) {        DisplayMetrics dm = getDM(context);        int SCREEN_WIDTH = dm.widthPixels;        image_width = (int) ((SCREEN_WIDTH - 3 * dip2px(context, offset)) / 2);        image_height = (int) (image_width * scale);    }        /**     * 得到屏幕参数     * @param activity     * @return pin     * @author chenchen  2014-11-20     */    public DisplayMetrics getDM(Activity activity) {        DisplayMetrics dm = new DisplayMetrics();        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);        return dm;    }        /**     * 将dp转换为px     * @param context 上下文     * @param dipValue dp值     * @return px值     * @author chenchen  2014-11-20     */    public float dip2px(Context context, float dipValue) {        float scale = context.getResources().getDisplayMetrics().density;        return dipValue * scale + 0.5f;    }


在initialParams方法中,首先得到DisplayMetrics对象,用来得到屏幕的尺寸信息。然后通过整体的宽度减去所有的间隔距离,再除以一行的条目数,确定每一项的宽度值。最后通过scale比例,确定每一项的高度值。这里注意这个间隔距离,因为在xml设置的间距单位是dp,在代码中设置的是px,因为为了统一要进行转换操作。


得到了尺寸信息,接下来就是设置尺寸了。在Adapter的getView方法中,实例化View的时候进行设置。这儿别忘了用缓存原理。
    @Override    public View getView(int position, View convertView, ViewGroup parent) {        if(convertView == null){            convertView = View.inflate(context, R.layout.item, null);                        ImageView dog_iv = (ImageView) convertView.findViewById(R.id.iv_dog);            ViewGroup.LayoutParams param_iv = dog_iv.getLayoutParams();            param_iv.width = image_width;            param_iv.height = image_height;            dog_iv.setLayoutParams(param_iv);                        RelativeLayout relativeLayout = (RelativeLayout) convertView.findViewById(R.id.relativeLayout);            ViewGroup.LayoutParams param_rl = relativeLayout.getLayoutParams();            param_rl.width = image_width;            relativeLayout.setLayoutParams(param_rl);        }        return convertView;    }

可以看见,首先用缓存原理对convertView进行非空判断。然后分别设置了Item项的ImageView和RelativeLayout的尺寸。这儿要特别提醒一下:因为RelativeLayout的尺寸改变了,若想将这个改变应用到子控件中,那么所有子空间都应该将layout_width设置为match_parent。这个大家应该都了解吧。我在这儿给所有控件默认值,大家要根据自己的实际情况,在这个方法里面设置不同的值。

0 0
原创粉丝点击