1.组合使用weightSum和layout_weight
这样使Button在LinearLayout中总是占据50%的宽度<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" android:gravity="center" android:orientation="horizontal" android:weightSum="1" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.5" android:text="@string/activity_main_click_me" /> </LinearLayout>
2.避免重复加载以及使用懒加载(lazy loading)
如果一个layout需要在不同布局中使用,比如说一个要在LinearLayout中使用,一个要在RelativeLayout中使用,如何保持这个layout在不同的布局中都处于底部呢?可以在<include/>标签中写这个layout的属性,不同布局写不同的属性。<include layout="@layout/footer_with_layout_properties"/>
2. <ViewStub/>标签实现懒加载
ViewStub的官方解释: A ViewStub is an invisible, zero-sized View that can be used to lazily inflate layout resources at runtime. When a ViewStub is made visible, or when inflate() is invoked, the layout resource is inflated. The ViewStub then replaces itself in its parent with the inflated View or Views.可见ViewStub在创建视图的时候是不加载的,只有当程序运行过程中需要的时候再加载,这样可以提高程序的运行效率。
那么如何使用<ViewStub/>呢?
ViewStub的标签通过layout指向一个布局,其中inflatedId是程序调用inflate()或者setVisibility()方法之后被填充进来的布局的id,这里也就是整个map布局的id。如果需要控制map布局中某一个控件,则可以在map布局中单独为控件设置id。<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" />
如果只需要加载布局显示给用户看,在java代码中只需要如下操作:
如果还需要对布局进行操作,则: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); }
ViewStub mViewStub = findViewById(R.id.map_stub); mViewStub.inflate(); //如果布局中还有其他控件,比如TextView,则可以直接初始化 TextView mTextView=(TextView)findViewById(R.id.map_stub_textview);
3. 自定义ViewGroup
1.自定义属性
在res/values文件夹下新建attrs.xml文件<resources> <declare-styleable name="CascadeLayout"> <attr name="horizontal_spacing" format="dimension" /> <attr name="vertical_spacing" format="dimension" /> </declare-styleable> <declare-styleable name="CascadeLayout_LayoutParams"> <attr name="layout_vertical_spacing" format="dimension" /> </declare-styleable> </resources>
在布局中引用自定义的控件
<FrameLayout xmlns:cascade="http://schemas.android.com/apk/res/com.manning.androidhacks.hack003" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.manning.androidhacks.hack003.view.CascadeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" cascade:horizontal_spacing="30dp" cascade:vertical_spacing="20dp" > <View android:layout_width="100dp" android:layout_height="150dp" android:background="#00FF00" /> <View android:layout_width="100dp" android:layout_height="150dp" android:background="#0000FF" /> </com.manning.androidhacks.hack003.view.CascadeLayout> </FrameLayout>
在自定义控件的类的构造函数中获取自定义的属性值
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(); } }
2. 自定义ViewGroup类
主要实现onMeasure和onLayout两个方法,在onMeasure方法中对子view进行测量,在onLayout中确定子view的位置。
详见:Android 手把手教您自定义ViewGroup(一)
具体实现:Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
3.使用PreferenceActivity
贴一个链接,就不写详细实现步骤了:
Android实战技巧之六:PreferenceActivity使用详解