开发 高质量 android应用 pdf,《打造高质量Android应用》读书笔记

前言

最近看到一本书,是开发安卓的一些小技巧和基础知识,大家一起查漏补缺吧!只有一部分,其他的有点老了,还有一些不感兴趣,没继续看了,所以只有9个知识点哦

1. 使用weight和weightsum属性实现视图居中

......

android:gravity="center"

android:orientation="horizontal"

android:weightSum="1" > //

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="0.5" //确保按钮占据50%空间

......

/>

2. 在include里使用android:layout_*属性,重写include布局属性,实现复用

footer布局:

android:layout_width="0dp"

android:layout_height="0dp"

android:gravity="center"

android:text="@string/footer_text" />

include footer:

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_marginBottom="30dp"

layout="@layout/footer" />

......

/RelativeLayout>

3. ViewStub实现view的延迟加载

场景:让用户自己决定是否显示地图信息

地图view

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:clickable="true"

......

/>

使用ViewStub

android:id="@+id/map_stub"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:inflatedId="@+id/map_view"

android:layout="@layout/map" />

在Activity中调用

private View mViewStub;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

mViewStub = findViewById(R.id.map_stub);

}

public void onShowMap(View v) {

mViewStub.setVisibility(View.VISIBLE);

}

......

inflatedId是调用ViewStub的inflate()方法或setVisibility()方法是返回的ID,这个ID便是被填充的View的ID,避免了使用findViewById()方法

4.定制ViewGroup

绘制布局由两个遍历过程组成:测量过程和布局过程。测量过程由measure(int, int)方法完成,该方法从上到下遍历视图树。在递归遍历过程中,每个视图都会向下层传递尺寸和规格。当measure方法遍历结束,每个视图都保存了各自的尺寸信息。第二个过程由layout(int,int,int,int)方法完成,该方法也是由上而下遍历视图树,在遍历过程中,每个父视图通过测量过程的结果定位所有子视图的位置信息。

为了理解这个概念,下面分析ViewGroup的绘制过程,第一步是测量ViewGroup的宽度和高度,在onMeasure方法中完成这个步骤。在该方法中,ViewGroup通过遍历所有子视图计算它的大小。最后一步操作,在onLayout()方法中完成,利用上一步计算出的测量信息,布局所有子视图。

作者实现了如下布局:

5e37cf85ec15

1>在values下创建attrs.xml,自定义属性

//属性名前缀是layout_,因此该属性会被添加到LayoutParams的属性表中

2>布局

xmlns:anyname="http://schemas.android.com/apk/res-auto"

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

android:layout_width="fill_parent"

android:layout_height="fill_parent"

anyname:horizontal_spacing="30dp"

anyname:vertical_spacing="20dp" >

android:layout_width="100dp"

android:layout_height="150dp"

anyname:layout_vertical_spacing="90dp"

android:background="#FF0000" />

android:layout_width="100dp"

android:layout_height="150dp"

android:background="#00FF00" />

android:layout_width="100dp"

android:layout_height="150dp"

android:background="#0000FF" />

3>自定义CascadeLayout

public class CascadeLayout extends ViewGroup {

private int mHorizontalSpacing;

private int mVerticalSpacing;

public CascadeLayout(Context context, AttributeSet attrs) {

super(context, attrs);

TypedArray a = context.obtainStyledAttributes(attrs,

R.styleable.CascadeLayout);

try {

mHorizontalSpacing = a.getDimensionPixelSize(

R.styleable.CascadeLayout_horizontal_spacing,

getResources().getDimensionPixelSize(

R.dimen.cascade_horizontal_spacing));

mVerticalSpacing = a.getDimensionPixelSize(

R.styleable.CascadeLayout_vertical_spacing, getResources()

.getDimensionPixelSize(R.dimen.cascade_vertical_spacing));

} finally {

a.recycle();

}

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// 使用宽和高计算布局的最终大小以及子视图的x和y轴位置

int width = getPaddingLeft();

int height = getPaddingTop();

int verticalSpacing;

final int count = getChildCount();

for (int i = 0; i < count; i++) {

verticalSpacing = mVerticalSpacing;

View child = getChildAt(i);

measureChild(child, widthMeasureSpec, heightMeasureSpec); //令每个子视图测量自身

LayoutParams lp = (LayoutParams) child.getLayoutParams();

width = getPaddingLeft() + mHorizontalSpacing * i;

// 在LayoutParams中保存每个子视图的x、y坐标

lp.x = width;

lp.y = height;

if (lp.verticalSpacing >= 0) {

verticalSpacing = lp.verticalSpacing;

}

width += child.getMeasuredWidth();

height += verticalSpacing;

}

width += getPaddingRight();

height += getChildAt(getChildCount() - 1).getMeasuredHeight()

+ getPaddingBottom();

setMeasuredDimension(resolveSize(width, widthMeasureSpec),

resolveSize(height, heightMeasureSpec)); // 用计算所得宽高设置整个布局的测量尺寸

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

final int count = getChildCount();

for (int i = 0; i < count; i++) {

View child = getChildAt(i);

LayoutParams lp = (LayoutParams) child.getLayoutParams();

child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y

+ child.getMeasuredHeight());

}

}

@Override

protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {

return p instanceof LayoutParams;

}

@Override

protected LayoutParams generateDefaultLayoutParams() {

return new LayoutParams(LayoutParams.WRAP_CONTENT,

LayoutParams.WRAP_CONTENT);

}

@Override

public LayoutParams generateLayoutParams(AttributeSet attrs) {

return new LayoutParams(getContext(), attrs);

}

@Override

protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {

return new LayoutParams(p.width, p.height);

}

public static class LayoutParams extends ViewGroup.LayoutParams {

int x;

int y;

public int verticalSpacing;

public LayoutParams(Context context, AttributeSet attrs) {

super(context, attrs);

TypedArray a = context.obtainStyledAttributes(attrs,

R.styleable.CascadeLayout_LayoutParams);

try {

verticalSpacing = a

.getDimensionPixelSize(

R.styleable.CascadeLayout_LayoutParams_layout_vertical_spacing,

-1);

} finally {

a.recycle();

}

}

public LayoutParams(int w, int h) {

super(w, h);

}

}

}

5. TextSwitcher和ImageSwitcher实现平滑过渡

TextSwitcher: 为文本标签添加动画效果

ImageSwitcher : 为图片切换添加动画效果

mTextSwitcher.setFactory(new ViewFactory() {

@Override

public View makeView() {

TextView t = new TextView(MainActivity.this);

t.setGravity(Gravity.CENTER);

return t;

}

});

mTextSwitcher.setInAnimation(this, android.R.anim.fade_in);

mTextSwitcher.setOutAnimation(this, android.R.anim.fade_out);

mTextSwitcher.setText("hello");

6. 避免在Edittext中验证日期

在应用程序中使用Android内置资源是一个借用设备样式的好方法,如

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@android:drawable/edit_text"

/>

7. 格式化TextView的文本,如链接、不同样式文本等

链接:

textView1.setText(Html.fromHtml("Manning home page]]>"));

textView1.setMovementMethod(LinkMovementMethod.getInstance());

不同样式

final Spannable text2 = new SpannableString(

getString(R.string.text2));

text2.setSpan(new BackgroundColorSpan(Color.RED), 1, 4, 0);

text2.setSpan(new ForegroundColorSpan(Color.BLUE), 5, 9, 0);

XX.setText(text2);

8. 横竖屏

设置android:configChanges="orientation"就不会重启Activity,而是调用onConfigurationChanged()方法

9. 移除窗口默认背景提高应用程序启动速度

@null

true

9.更改toast显示位置

Toast toast = Toast.makeText(this, "Upper Left!",

Toast.LENGTH_SHORT);

toast.setGravity(Gravity.TOP | Gravity.LEFT, 0, 0);

toast.show();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值