Android 屏幕适配最佳实践

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

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
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值