android屏幕适配
今日头条的适配方式:
采用的是鸿阳的适配方式,项目依赖:
compile 'com.zhy:autolayout:1.4.5'
使用步骤:
在manifest文件中标注你的设计图尺寸 注意:做适配的时候一定要严格按照设计图上的尺寸来开发
有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};#endimport 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); } }}