首先来看一下我实现的效果图:
从”我的关注”开始,每一个条目都是一个自定义组合控件.下面,我来讲解一下具体实现步骤:
一.根据知乎的样式,创建并完成布局文件.
在本页面所有的自定义组件中,只有”夜间模式”一项最为复杂,在条目布局的右侧增加了一个按钮,所以我们就选择它作为自定义组件的基础布局.
具体布局如下:
<pre name="code" class="html"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/selector_msi">
<ImageView
android:id="@+id/iv_more_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="15dp"
android:src="@drawable/ic_remove_red_eye_white_18dp"
android:tint="@android:color/darker_gray" />
<TextView
android:id="@+id/tv_moretext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/iv_more_icon"
android:paddingLeft="15dp"
android:text="我的关注"
android:textSize="16sp" />
<ImageView
android:id="@+id/iv_more_line"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_alignLeft="@+id/tv_moretext"
android:layout_alignParentBottom="true"
android:layout_marginLeft="15dp"
android:background="@drawable/list_divider"
android:tint="@android:color/darker_gray"></ImageView>
<Switch
android:id="@+id/switch_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:paddingRight="10dp"
android:visibility="invisible"
/>
</RelativeLayout>
二.设置自定义组件的属性
在res文件夹中,找到values文件夹,创建attrs.xml文件,在里面就可以对自定义组件的属性进行设置了,具体代码如下:
<pre name="code" class="html"><declare-styleable name="MorePersonalSettingItem">
<!--设置条目文字-->
<attr name="moretext" format="string" ></attr>
<!--设置条目是否显示下方横线-->
<attr name="isShowLine" format="boolean"></attr>
<!--设置条目图片样式-->
<attr name="moreicon" format="reference"></attr>
<!--设置条目是否显示右侧按钮-->
<attr name="isShowToggle" format="boolean"></attr>
</declare-styleable>
三.创建自定义组件类,继承相应的布局,并给相应属性设置业务逻辑
为了使自定义组件的属性发挥作用,我们还需要通过代码实现对应的业务逻辑,这就需要创建自定义组件的类了,根据组件布局特点,我们让它继承RelativeLayout布局,当然其他布局也可以,感兴趣的朋友可以自行尝试.我的自定义组件命名为MorePersonalSettingItem.
具体实现代码如下:
public class MorePersonalSettingItem extends RelativeLayout {
private static final String NAMESPACE = "http://schemas.android.com/apk/res-auto";
private ImageView iv_more_icon;
private ImageView iv_more_line;
private TextView tv_moretext;
private Switch switch_more;
public MorePersonalSettingItem(Context context) {
this(context,null);
}
public MorePersonalSettingItem(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public MorePersonalSettingItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//找到各个属性
String moreText = attrs.getAttributeValue(NAMESPACE,"moretext");
Boolean isShowLine = attrs.getAttributeBooleanValue(NAMESPACE,"isShowLine",true);
int moreicon = attrs.getAttributeResourceValue(NAMESPACE, "moreicon", R.drawable.ic_live_tiny);
Boolean isShowToggle = attrs.getAttributeBooleanValue(NAMESPACE,"isShowToggle",false);
initView();
iv_more_icon.setImageResource(moreicon);
tv_moretext.setText(moreText);
//判断是否显示横线
if(isShowLine){
iv_more_line.setVisibility(View.VISIBLE);
} else {
iv_more_line.setVisibility(View.INVISIBLE);
}
//判断是否显示按钮
if(isShowToggle){
switch_more.setVisibility(View.VISIBLE);
} else {
switch_more.setVisibility(View.INVISIBLE);
}
}
public void initView(){
//加载布局
View view = View.inflate(getContext(), R.layout.more_setting_item,null);
iv_more_icon = (ImageView)view.findViewById(R.id.iv_more_icon);
iv_more_line = (ImageView)view.findViewById(R.id.iv_more_line);
tv_moretext = (TextView)view.findViewById(R.id.tv_moretext);
switch_more = (Switch)view.findViewById(R.id.switch_more);
addView(view);
}
}
四.使用自定义组件
这时候,我们的自定义组件就算创建完成了,可以到相应的布局文件中直接使用了.需要注意的是,在使用自定义组件的时候,一定要在组件名称前加上全包名,
并在外层大布局添加属性:
xmlns:app="http://schemas.android.com/apk/res-auto"
这样,在编译的时候才能找到对应的控件和属性,否则会报错
使用实例代码如下:
<!--第二块内容,个人设置--> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="6dp" android:orientation="vertical"> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_my_concern" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="true" app:moreicon="@drawable/ic_follow_more" app:moretext="我的关注"></com.example.zhihu10.ui.MorePersonalSettingItem> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_my_collect" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="true" app:moreicon="@drawable/ic_grade" app:moretext="我的收藏"></com.example.zhihu10.ui.MorePersonalSettingItem> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_my_draft" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="true" app:moreicon="@drawable/ic_draft_more" app:moretext="我的草稿"></com.example.zhihu10.ui.MorePersonalSettingItem> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_my_scan_nearby" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="true" app:moreicon="@drawable/ic_recent_views" app:moretext="最近浏览"></com.example.zhihu10.ui.MorePersonalSettingItem> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_my_zhihu" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="true" app:moreicon="@drawable/ic_zhi_logo" app:moretext="我的值乎"></com.example.zhihu10.ui.MorePersonalSettingItem> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_my_live" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="false" app:moreicon="@drawable/ic_feed_livebanner_logo" app:moretext="我的Live"></com.example.zhihu10.ui.MorePersonalSettingItem> </LinearLayout> <!--第三块内容,属性设置--> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" android:orientation="vertical"> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_night_mode" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="true" app:isShowToggle="true" app:moreicon="@drawable/ic_nightmode_more" app:moretext="夜间模式"></com.example.zhihu10.ui.MorePersonalSettingItem> <com.example.zhihu10.ui.MorePersonalSettingItem android:id="@+id/msi_my_setting" android:layout_width="match_parent" android:layout_height="50dp" app:isShowLine="false" app:moreicon="@drawable/ic_drawer_settings" app:moretext="设置"></com.example.zhihu10.ui.MorePersonalSettingItem> </LinearLayout> </LinearLayout>
好啦,自定义组件的简单使用我们就讲完了,当然这只是非常简单的例子,通过自定义组件,我们可以完成更多Android自带控件所不能完成的功能,进而实现更为复杂的布局和设置更美观的页面,这些就留待以后在具体的案例中讲解吧.
最后,感谢大家浏览我的博客,希望在Android开发的道路上一起成长!
对应的项目的GitHub地址为:https://github.com/WanXuJiao/ZhiHu1.0
项目还在编辑过程中,已完成整体框架和布局,也希望有高手大神能帮助加以改进.