Android 屏幕适配最佳实践

来源:互联网 发布:索尼z3 网络待机 编辑:程序博客网 时间:2024/06/05 11:55

参考该文章理论知识加代码

Android 屏幕适配方案

但是呢,该篇博文里个人觉得代码封装的不是很好,于是自己封装了下,使用XStream生成xml。上面那篇文章里没有对横竖屏进行适配,代码里完善了这一点,对横竖屏进行了适配。
在开始码代码前,贴一张图,结合前面那篇文章的理论知识一起看。
这里写图片描述
然后呢看最终适配的效果,这里以320*480为基准,屏幕上放一个TextView,宽度为x160,高度为y240,效果图如下
这里写图片描述

然后呢,不要惊讶,你会发现里面的两个pad并没有适配,其实呢,我也母鸡呀,但是我开了一个模拟器,启动了一个pad,其实是适配了。于是就没有然后了,有兴趣的再研究下吧。

先封装Screen类

package cn.edu.zafu.model;/** * @author lizhangqu * @description * @date */public class Screen {    private int width;    private int height;    public Screen(int width, int height) {        this.width = width;        this.height = height;    }    public int getWidth() {        return width;    }    public void setWidth(int width) {        this.width = width;    }    public int getHeight() {        return height;    }    public void setHeight(int height) {        this.height = height;    }    public String getDir(boolean portrait) {        // landscape是横向,portrait是纵向        if (portrait) {            return String.format("values-%dx%d", height, width);        } else {            return String.format("values-land-%dx%d", height, width);        }    }    @Override    public String toString() {        return "Screen [width=" + width + ", height=" + height + "]";    }}

其次是Rescource类,使用注解

package cn.edu.zafu.model;import java.util.ArrayList;import java.util.List;import com.thoughtworks.xstream.annotations.XStreamAlias;import com.thoughtworks.xstream.annotations.XStreamImplicit;/** * @author lizhangqu * @description  * @date  */@XStreamAlias("resources")public class Resource {    @XStreamImplicit(itemFieldName = "dimen")    List<Dimen> dimens = new ArrayList<Dimen>();    public Resource() {    }    public Resource(List<Dimen> dimens) {        this.dimens = dimens;    }    public List<Dimen> getDimens() {        return dimens;    }    public void setDimens(List<Dimen> dimens) {        this.dimens = dimens;    }    @Override    public String toString() {        return "Resource [dimens=" + dimens + "]";    }}

Dimen类,依然使用注解

package cn.edu.zafu.model;import com.thoughtworks.xstream.annotations.XStreamAlias;import com.thoughtworks.xstream.annotations.XStreamAsAttribute;import com.thoughtworks.xstream.annotations.XStreamConverter;import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter;/** * @author lizhangqu * @description  * @date  */@XStreamAlias("dimen")@XStreamConverter(value = ToAttributedValueConverter.class, strings = { "value" })public class Dimen {    @XStreamAlias("name")    @XStreamAsAttribute()    private String name;    private String value;    public Dimen() {    }    public Dimen(String name, String value) {        this.name = name;        this.value = value;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getValue() {        return value;    }    public void setValue(String value) {        this.value = value;    }    @Override    public String toString() {        return "Dimen [name=" + name + ", value=" + value + "]";    }}

继承XStream类,默认的只会输出xml体,我们加入xml头

<?xml version="1.0" encoding="utf-8"?>
package cn.edu.zafu.util;import java.io.OutputStream;import java.io.Writer;import com.thoughtworks.xstream.XStream;/** * @author lizhangqu * @description  * @date  */public class XmlDeclarationXStream extends XStream {    private String xmlDeclaration;    private String version;    private String ecoding;    public XmlDeclarationXStream() {        this("1.0", "utf-8");    }    public XmlDeclarationXStream(String version, String ecoding) {        this.version = version;        this.ecoding = ecoding;        buildDeclaration();    }    private void buildDeclaration() {        // generate xmlDeclaration        StringBuffer buffer = new StringBuffer();        xmlDeclaration = buffer.append("<?xml version=\"").append(this.version)                .append("\" encoding=\"").append(this.ecoding).append("\"?>")                .append("\n").toString();        buffer = null;    }    public String getDeclaration() {        return xmlDeclaration;    }    @Override    public void toXML(Object arg0, OutputStream arg1) {        try {            String dec = this.getDeclaration();            byte[] bytesOfDec = dec.getBytes(this.ecoding);            arg1.write(bytesOfDec);        } catch (Exception e) {            e.printStackTrace();        }        super.toXML(arg0, arg1);    }    @Override    public void toXML(Object arg0, Writer arg1) {        try {            arg1.write(getDeclaration());        } catch (Exception e) {            e.printStackTrace();        }        super.toXML(arg0, arg1);    }}

最后是生成资源文件的工具类,见注释

package cn.edu.zafu.util;import java.io.BufferedWriter;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.text.DecimalFormat;import java.util.List;import cn.edu.zafu.model.Dimen;import cn.edu.zafu.model.Resource;import cn.edu.zafu.model.Screen;import com.thoughtworks.xstream.XStream;/** *  * @author lizhangqu * @description a tool to generate what we want * @date */public class Generator {    // default base width    private static final int DEFAULT_BASE_WIDTH = 320;    // default base height    private static final int DEFAULT_BASE_HEIGHT = 480;    // decimal formator    private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(            "#.##");    // a xstream,XmlDeclarationXStream extends XStream    private static final XStream XSTREAM = new XmlDeclarationXStream();    //res dir    private File resFile=null;    // base width    private int baseWidth;    // base height    private int beseHeight;    /**     * using default width and height to generate default width is 320,default     * height is 480     */    public Generator() {        this(DEFAULT_BASE_WIDTH, DEFAULT_BASE_HEIGHT);    }    /**     * using baseWidth and baseHeight to generator     *      * @param baseWidth     * @param beseHeight     */    public Generator(int baseWidth, int beseHeight) {        this.baseWidth = baseWidth;        this.beseHeight = beseHeight;        XSTREAM.autodetectAnnotations(true);        this.resFile = new File("./res");        if (!resFile.exists()) {            resFile.mkdir();        }    }    /**     * using w and h to generate xml     *      * @param w     *            screen width     * @param h     *            screen height     * @return generated xml     */    public String generateXml(Screen screen) {        Resource resource = new Resource();        List<Dimen> dimens = resource.getDimens();        float cellWidth = screen.getWidth() * 1.0f / baseWidth;        float cellHeight = screen.getHeight() * 1.0f / beseHeight;        String result = null;        Dimen dimen = null;        for (int i = 1; i <= baseWidth; i++) {            result = DECIMAL_FORMAT.format(i * cellWidth);            dimen = new Dimen();            dimen.setName(String.format("x%d", i));            dimen.setValue(String.format("%spx", result));            dimens.add(dimen);        }        for (int i = 1; i <= beseHeight; i++) {            result = DECIMAL_FORMAT.format(i * cellHeight);            dimen = new Dimen();            dimen.setName(String.format("y%d", i));            dimen.setValue(String.format("%spx", result));            dimens.add(dimen);        }        String xml = XSTREAM.toXML(resource);        return xml;    }    public String generateXmlLandscape(Screen screen) {        Screen s=new Screen(screen.getHeight(),screen.getWidth());        return generateXml(s);    }    /**     * write xmlContent to a File     *      * @param screen     * @param xmlContent     */    public void write2File(String valuesPath, String xmlContent) {        File fileDir = new File(this.resFile + File.separator + valuesPath);        fileDir.mkdir();        File file = new File(fileDir.getAbsolutePath(), "dimens.xml");        BufferedWriter bw = null;        FileOutputStream fos = null;        try {            fos = new FileOutputStream(file);            bw = new BufferedWriter(new OutputStreamWriter(fos));            bw.write(xmlContent);        } catch (IOException e) {            e.printStackTrace();        }  finally {            try {                if (bw != null) {                    bw.close();                    bw = null;                }                if (fos != null) {                    fos.close();                    fos = null;                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}

主函数,生成常见分辨率的资源文件

package cn.edu.zafu;import java.util.ArrayList;import java.util.List;import cn.edu.zafu.model.Screen;import cn.edu.zafu.util.Generator;/** * @author lizhangqu * @description * @date */public class Main {    public static void main(String[] args) {        new Main().bulid();    }    public void bulid() {        Generator generator = new Generator(320, 480);        List<Screen> screens = new ArrayList<Screen>();        Screen screen = null;        screen = new Screen(320, 400);        screens.add(screen);        screen = new Screen(320, 480);        screens.add(screen);        screen = new Screen(480, 800);        screens.add(screen);        screen = new Screen(480, 854);        screens.add(screen);        screen = new Screen(540, 960);        screens.add(screen);        screen = new Screen(600, 1024);        screens.add(screen);        screen = new Screen(720, 1184);        screens.add(screen);        screen = new Screen(720, 1196);        screens.add(screen);        screen = new Screen(720, 1280);        screens.add(screen);        screen = new Screen(768, 1024);        screens.add(screen);        screen = new Screen(768, 1280);        screens.add(screen);        screen = new Screen(800, 1280);        screens.add(screen);        screen = new Screen(1080, 1812);        screens.add(screen);        screen = new Screen(1080, 1920);        screens.add(screen);        screen = new Screen(1200, 1920);        screens.add(screen);        screen = new Screen(1440, 2560);        screens.add(screen);        screen = new Screen(2048, 1536);        screens.add(screen);        screen = new Screen(2560, 1600);        screens.add(screen);        int size = screens.size();        for (int i = 0; i < size; i++) {            String portrait = generator.generateXml(screens.get(i));            generator.write2File(screens.get(i).getDir(true), portrait);            String landscape = generator.generateXmlLandscape(screens.get(i));            generator.write2File(screens.get(i).getDir(false), landscape);            System.out.println("create file "+i+" success");        }        System.out.println("success");    }}

源码下载
github下载:AndroidScreenAdapter

csdn下载:AndroidScreenAdapter

3 0
原创粉丝点击