android屏幕适配
今日头条的适配方式:https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA
采用的是鸿阳的适配方式,项目依赖:
compile 'com.zhy:autolayout:1.4.5'
使用步骤:
在manifest文件中标注你的设计图尺寸 注意:做适配的时候一定要严格按照设计图上的尺寸来开发
<meta-data android:name="design_width" android:value="768">
</meta-data>
<meta-data android:name="design_height" android:value="1280">
</meta-data>
有2中方式使用:
第一种直接在activity中处理,直接把AutoLinearLayout、AutoRelativeLayout、AutoFrameLayout转换成LinearLayout、RelativeLayout、FrameLayout,在布局文件XML中可以直接使用:
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.util.AttributeSet;
import android.view.View;
;
/**
* Created by zhy on 15/11/19.
*/
public class AutoLayoutActivity extends AppCompatActivity
{
private static final String LAYOUT_LINEARLAYOUT = "LinearLayout";
private static final String LAYOUT_FRAMELAYOUT = "FrameLayout";
private static final String LAYOUT_RELATIVELAYOUT = "RelativeLayout";
@Override
public View onCreateView(String name, Context context, AttributeSet attrs)
{
View view = null;
if (name.equals(LAYOUT_FRAMELAYOUT))
{
view = new AutoFrameLayout(context, attrs);
}
if (name.equals(LAYOUT_LINEARLAYOUT))
{
view = new AutoLinearLayout(context, attrs);
}
if (name.equals(LAYOUT_RELATIVELAYOUT))
{
view = new AutoRelativeLayout(context, attrs);
}
if (view != null) return view;
return super.onCreateView(name, context, attrs);
}
}
第二种就是在布局中直接使用AutoLinearLayout、AutoRelativeLayout、AutoFrameLayout
这些布局所支持的属性为:
- layout_width
- layout_height
- layout_margin(left,top,right,bottom)
- pading(left,top,right,bottom)
- textSize
- maxWidth, minWidth, maxHeight, minHeight
模板方式:AutoView
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.ViewGroup;
import com.zhy.autolayout.AutoLayoutInfo;
import com.zhy.autolayout.utils.AutoLayoutHelper;
/**
* 此Template用于生成AutoLayout需要的的Auto系列View,如需要使ScrollView适配,使用此Template输入ScrollView,即可生成
* AutoScrollView,使用此View即可自适应
* Created by jess on 16/4/14.
*/
public class Auto${NAME} extends ${NAME} {
private AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public Auto${NAME}(Context context) {
super(context);
}
public Auto${NAME}(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public Auto${NAME}(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
mHelper.adjustChildren();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends ${NAME}.LayoutParams
implements AutoLayoutHelper.AutoLayoutParams
{
private AutoLayoutInfo mAutoLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs)
{
super(c, attrs);
mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
}
@Override
public AutoLayoutInfo getAutoLayoutInfo()
{
return mAutoLayoutInfo;
}
public LayoutParams(int width, int height)
{
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source)
{
super(source);
}
public LayoutParams(MarginLayoutParams source)
{
super(source);
}
}
}
1.实例1:AutoActionMenuItemView
public class AutoActionMenuItemView extends ActionMenuItemView {
private static final int NO_VALID = -1;
private int mMenuTextSize;
public AutoActionMenuItemView(Context context) {
this(context, null);
}
public AutoActionMenuItemView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.Theme,
defStyle, R.style.ThemeOverlay_AppCompat);
int menuTextAppearance = a.getResourceId(R.styleable.Theme_actionBarTheme,
R.style.ThemeOverlay_AppCompat_ActionBar);
mMenuTextSize = loadTextSizeFromTextAppearance(menuTextAppearance);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!this.isInEditMode()) {
setUpTitleTextSize();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private int loadTextSizeFromTextAppearance(int textAppearanceResId) {
TypedArray a = getContext().obtainStyledAttributes(textAppearanceResId,
R.styleable.TextAppearance);
try {
if (!DimenUtils.isPxVal(a.peekValue(R.styleable.TextAppearance_android_textSize)))
return NO_VALID;
return a.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, NO_VALID);
} finally {
a.recycle();
}
}
private void setUpTitleTextSize() {
if (mMenuTextSize == -1) return;
int autoTextSize = AutoUtils.getPercentHeightSize(mMenuTextSize);
setTextSize(TypedValue.COMPLEX_UNIT_PX, autoTextSize);
}
}
2. 实例2:AutoCardView
public class AutoCardView extends CardView
{
private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public AutoCardView(Context context)
{
super(context);
}
public AutoCardView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public AutoCardView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
}
@Override
public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new AutoFrameLayout.LayoutParams(getContext(), attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
{
mHelper.adjustChildren();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
3.0 实例3: AutoRadioGroup
public class AutoRadioGroup extends RadioGroup
{
private AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public AutoRadioGroup(Context context)
{
super(context);
}
public AutoRadioGroup(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
mHelper.adjustChildren();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs)
{
return new LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends RadioGroup.LayoutParams
implements AutoLayoutHelper.AutoLayoutParams
{
private AutoLayoutInfo mAutoLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs)
{
super(c, attrs);
mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
}
@Override
public AutoLayoutInfo getAutoLayoutInfo()
{
return mAutoLayoutInfo;
}
public LayoutParams(int width, int height)
{
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source)
{
super(source);
}
public LayoutParams(MarginLayoutParams source)
{
super(source);
}
}
4.0 实例4:AutoTabLayout
public class AutoTabLayout extends TabLayout
{
private static final int NO_VALID = -1;
private int mTextSize;
private boolean mTextSizeBaseWidth = false;
public AutoTabLayout(Context context)
{
this(context, null);
}
public AutoTabLayout(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public AutoTabLayout(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
initTextSizeBaseWidth(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabLayout,
defStyleAttr, R.style.Widget_Design_TabLayout);
int tabTextAppearance = a.getResourceId(R.styleable.TabLayout_tabTextAppearance,
R.style.TextAppearance_Design_Tab);
mTextSize = loadTextSizeFromTextAppearance(tabTextAppearance);
a.recycle();
}
private void initTextSizeBaseWidth(Context context, AttributeSet attrs)
{
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoTabLayout);
mTextSizeBaseWidth = a.getBoolean(R.styleable.AutoTabLayout_auto_textSize_base_width, false);
a.recycle();
}
private int loadTextSizeFromTextAppearance(int textAppearanceResId)
{
TypedArray a = getContext().obtainStyledAttributes(textAppearanceResId,
R.styleable.TextAppearance);
try
{
if (!DimenUtils.isPxVal(a.peekValue(R.styleable.TextAppearance_android_textSize)))
return NO_VALID;
return a.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, NO_VALID);
} finally
{
a.recycle();
}
}
@Override
public void addTab(Tab tab, int position, boolean setSelected)
{
super.addTab(tab, position, setSelected);
setUpTabTextSize(tab);
}
@Override
public void addTab(Tab tab, boolean setSelected)
{
super.addTab(tab, setSelected);
setUpTabTextSize(tab);
}
private void setUpTabTextSize(Tab tab)
{
if (mTextSize == NO_VALID || tab.getCustomView() != null) return;
ViewGroup tabGroup = (ViewGroup) getChildAt(0);
ViewGroup tabContainer = (ViewGroup) tabGroup.getChildAt(tab.getPosition());
TextView textView = (TextView) tabContainer.getChildAt(1);
if (AutoUtils.autoed(textView))
{
return;
}
int autoTextSize = 0 ;
if (mTextSizeBaseWidth)
{
autoTextSize = AutoUtils.getPercentWidthSize(mTextSize);
} else
{
autoTextSize = AutoUtils.getPercentHeightSize(mTextSize);
}
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, autoTextSize);
}
}
5.0 实例5 :AutoToolbar
public class AutoToolbar extends Toolbar {
private static final int NO_VALID = -1;
private int mTextSize;
private int mSubTextSize;
private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public AutoToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Toolbar,
defStyleAttr, R.style.Widget_AppCompat_Toolbar);
int titleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance,
R.style.TextAppearance_Widget_AppCompat_Toolbar_Title);
int subtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance,
R.style.TextAppearance_Widget_AppCompat_Toolbar_Subtitle);
mTextSize = loadTextSizeFromTextAppearance(titleTextAppearance);
mSubTextSize = loadTextSizeFromTextAppearance(subtitleTextAppearance);
TypedArray menuA = context.getTheme().obtainStyledAttributes(attrs, R.styleable.Theme,
defStyleAttr, R.style.ThemeOverlay_AppCompat);
int menuTextAppearance = menuA.getResourceId(R.styleable.Theme_actionBarTheme,
R.style.ThemeOverlay_AppCompat_ActionBar);
int menuTextSize = loadTextSizeFromTextAppearance(menuTextAppearance);
//防止 menu 定义 textSize,而 Toolbar 无定义 textSize 时,title 的 textSize 随 menu 变化
if (mTextSize == NO_VALID) mTextSize = menuTextSize;
if (mSubTextSize == NO_VALID) mSubTextSize = menuTextSize;
a.recycle();
menuA.recycle();
}
public AutoToolbar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoToolbar(Context context) {
this(context, null);
}
private int loadTextSizeFromTextAppearance(int textAppearanceResId) {
TypedArray a = getContext().obtainStyledAttributes(textAppearanceResId,
R.styleable.TextAppearance);
try {
if (!DimenUtils.isPxVal(a.peekValue(R.styleable.TextAppearance_android_textSize)))
return NO_VALID;
return a.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, NO_VALID);
} finally {
a.recycle();
}
}
private void setUpTitleTextSize() {
CharSequence title = getTitle();
if (!TextUtils.isEmpty(title) && mTextSize != NO_VALID)
setUpTitleTextSize("mTitleTextView", mTextSize);
CharSequence subtitle = getSubtitle();
if (!TextUtils.isEmpty(subtitle) && mSubTextSize != NO_VALID)
setUpTitleTextSize("mSubtitleTextView", mSubTextSize);
}
private void setUpTitleTextSize(String name, int val) {
try {
//反射 Toolbar 的 TextView
Field f = getClass().getSuperclass().getDeclaredField(name);
f.setAccessible(true);
TextView textView = (TextView) f.get(this);
if (textView != null) {
int autoTextSize = AutoUtils.getPercentHeightSize(val);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, autoTextSize);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!this.isInEditMode()) {
setUpTitleTextSize();
this.mHelper.adjustChildren();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(this.getContext(), attrs);
}
public static class LayoutParams extends Toolbar.LayoutParams implements AutoLayoutHelper.AutoLayoutParams {
private AutoLayoutInfo mDimenLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
this.mDimenLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
}
@Override
public AutoLayoutInfo getAutoLayoutInfo() {
return this.mDimenLayoutInfo;
}
public LayoutParams(int width, int height) {
super(width, height);
}
public LayoutParams(android.view.ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
}
}
6.0 实例6:AutoAppBarLayout
public class AutoAppBarLayout extends AppBarLayout {
private AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public AutoAppBarLayout(Context context) {
super(context);
}
public AutoAppBarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
mHelper.adjustChildren();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new AutoAppBarLayout.LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends AppBarLayout.LayoutParams
implements AutoLayoutHelper.AutoLayoutParams
{
private AutoLayoutInfo mAutoLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs)
{
super(c, attrs);
mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
}
@Override
public AutoLayoutInfo getAutoLayoutInfo()
{
return mAutoLayoutInfo;
}
public LayoutParams(int width, int height)
{
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source)
{
super(source);
}
public LayoutParams(ViewGroup.MarginLayoutParams source)
{
super(source);
}
}
}
7.0 实例7 : AutoCollapsingToolbarLayout
public class AutoCollapsingToolbarLayout extends CollapsingToolbarLayout {
private AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public AutoCollapsingToolbarLayout(Context context) {
super(context);
}
public AutoCollapsingToolbarLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoCollapsingToolbarLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
mHelper.adjustChildren();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new AutoCollapsingToolbarLayout.LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends CollapsingToolbarLayout.LayoutParams
implements AutoLayoutHelper.AutoLayoutParams
{
private AutoLayoutInfo mAutoLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs)
{
super(c, attrs);
mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
}
@Override
public AutoLayoutInfo getAutoLayoutInfo()
{
return mAutoLayoutInfo;
}
public LayoutParams(int width, int height)
{
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source)
{
super(source);
}
public LayoutParams(ViewGroup.MarginLayoutParams source)
{
super(source);
}
}
}
8.0 实例8: AutoScrollView
public class AutoScrollView extends ScrollView {
private AutoLayoutHelper mHelper = new AutoLayoutHelper(this);
public AutoScrollView(Context context) {
super(context);
}
public AutoScrollView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public AutoScrollView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (!isInEditMode())
mHelper.adjustChildren();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new AutoScrollView.LayoutParams(getContext(), attrs);
}
public static class LayoutParams extends ScrollView.LayoutParams
implements AutoLayoutHelper.AutoLayoutParams
{
private AutoLayoutInfo mAutoLayoutInfo;
public LayoutParams(Context c, AttributeSet attrs)
{
super(c, attrs);
mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
}
@Override
public AutoLayoutInfo getAutoLayoutInfo()
{
return mAutoLayoutInfo;
}
public LayoutParams(int width, int height)
{
super(width, height);
}
public LayoutParams(ViewGroup.LayoutParams source)
{
super(source);
}
public LayoutParams(MarginLayoutParams source)
{
super(source);
}
}
}