xamarin android自定义标题栏(自定义属性、回调事件)
来源:互联网 发布:ubuntu中怎么安装qq 编辑:程序博客网 时间:2024/06/06 00:23
自定义控件的基本要求
这篇文章就当是自定义控件入门,看了几篇android关于自定义控件的文章,了解了一下,android自定义控件主要有3种方式:
- 自绘控件:继承View类,所展示的内容在OnDraw方法中绘制出来
- 组合控件:不需要绘制视图显示的内容,只用系统原生的控件,将几个控件组合起来,(这就是这篇文章要写的自定义标题栏)
- 继承控件:继承原生的控件类,在原生的属性上增加新的功能。
这篇文章所要写的是第二种方式组合控件,来实现自定义标题栏。总结这4点实现一个组合控件的基本要求:
1.在XML布局中可设置组合控件自定义的属性。
2.在代码总可设置属性和方法。
3.UI交互:布局美观,按下,点击等效果。
4.自定义回调事件
先来看看最终实现的效果图:
自定义标题栏的实现(使用的是include标签)
自定义标题栏的好处:
- 提高布局效率
- 降低布局文件的维护成本
- 方便使用,容易扩展
- 降低标题栏和Activity代码逻辑的耦合
我们先来看看布局文件:TitleBar.axml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="56dp"> <Button android:id="@+id/titleBar_left_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:text="返回" android:drawableLeft="@drawable/icon_white_arrow_left" android:background="@android:color/transparent" android:textSize="14sp" /> <TextView android:id="@+id/title_bar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="测试标题" android:singleLine="true" android:textSize="17sp" /> <Button android:id="@+id/titleBar_right_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:text="提交" android:textSize="14sp" android:background="@android:color/transparent"/></RelativeLayout>
然后在需要的地方通过include标签引用
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <include layout="@layout/TitleBar" /></LinearLayout>
在MainActivity中添加单击事件,或者设置属性
[Activity(Label = "CustomeTitleBar", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : Activity { private TextView title_bar_title; private Button title_bar_left_btn; private Button title_bar_right_btn; protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView (Resource.Layout.Main); title_bar_left_btn = FindViewById<Button>(Resource.Id.titleBar_left_btn); title_bar_right_btn = FindViewById<Button>(Resource.Id.titleBar_right_btn); title_bar_title = FindViewById<TextView>(Resource.Id.title_bar_title); title_bar_title.Text = "新的标题"; title_bar_left_btn.Click += (s, e) => { Finish(); }; title_bar_right_btn.Click += (s, e) => { Toast.MakeText(this,"提交",ToastLength.Short).Show(); }; } }
上面的这种方式与我们自定义控件的要求相差较远,不能自定义属性,不能事件的回调。并不推荐这种方式。如果说一直用include标签的话,这个自定义标题栏好像是写给自己用的似的。
自定义标题栏的实现(自定义属性、回调事件)
(1)定义标题栏的组合布局
我们还是写来自定义一个布局,还是用上面的那个布局,不过最外层的根布局RelativeLayout就不要了,使用merge标签,避免这种嵌套布局
<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android"> <Button android:id="@+id/titleBar_left_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:gravity="left|center_vertical" android:background="@android:color/transparent" android:textSize="14sp" /> <TextView android:id="@+id/title_bar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:singleLine="true" android:textSize="17sp" /> <Button android:id="@+id/titleBar_right_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="5dp" android:background="@android:color/transparent" android:gravity="right|center_vertical" android:textSize="14sp" /></merge>
(2)自定标题栏相关的自定义属性
在values文件夹新建一个xml文件attrs.xml,关于android中自定义属性format的取值类型有以下这些:
- reference:如android:background = “@drawable/图片ID”
- color:如android:textColor = “#000000”
- boolean:如android:focusable = “false”
- dimenion:如android:layout_width = “10dp”
- float :如android:fromAlpha = “1.0”
- integer:如android:background = “@drawable/图片ID”
- string:如android:text=”123”
- fraction:百分数如:android:pivotY = “300%”
- enum:如android:orientation=”vertical”
<?xml version="1.0" encoding="utf-8" ?><resources> <declare-styleable name="CustomeTitleBar"> <attr name="title_background_color" format="color"/> <attr name="title_text" format="string"/> <attr name="title_text_color" format="color"/> <attr name="right_button_text" format="string"/> <attr name="right_button_text_color" format="color"/> <attr name="right_button_drawable" format="reference|integer"/> <attr name="right_button_visible" format="boolean"/> <attr name="left_button_text" format="string"/> <attr name="left_button_text_color" format="color"/> <attr name="left_button_drawable" format="reference|integer"/> <attr name="left_button_visible" format="boolean"/> </declare-styleable></resources>
(3)自定义标题栏代码的实现,根据不同的需求继承不同的原生ViewGroup类,这里继承的是RelativeLayout,也可以LinearLayout、EditText。
public class MyTitleBar : RelativeLayout { private TextView title_bar_title; private Button title_bar_left_btn; private Button title_bar_right_btn; public MyTitleBar(Context context, IAttributeSet attrs) : base(context, attrs) { //base(context, attrs); LayoutInflater.From(context).Inflate(Resource.Layout.TitleBar, this, true); title_bar_left_btn = FindViewById<Button>(Resource.Id.titleBar_left_btn); title_bar_right_btn = FindViewById<Button>(Resource.Id.titleBar_right_btn); title_bar_title = FindViewById<TextView>(Resource.Id.title_bar_title); try { TypedArray attributes = context.ObtainStyledAttributes(attrs, Resource.Styleable.CustomeTitleBar); if (attributes != null) { //titlebar 背景颜色 int titleBarBackground = attributes.GetResourceId(Resource.Styleable.CustomeTitleBar_title_background_color,Resource.Color.color_primary); SetBackgroundResource(titleBarBackground); //左边按钮 //是否显示 bool leftButtonVisible = attributes.GetBoolean(Resource.Styleable.CustomeTitleBar_left_button_visible, true); if (leftButtonVisible) { title_bar_left_btn.Visibility = ViewStates.Visible; } else { title_bar_left_btn.Visibility = ViewStates.Gone; } //设置左边按钮的文字和图标(二者只能选其一) string leftButtonText = attributes.GetString(Resource.Styleable.CustomeTitleBar_left_button_text); if (!string.IsNullOrEmpty(leftButtonText)) { title_bar_left_btn.Text = leftButtonText; //设置左边按钮的文字颜色 Color leftButtonTextColor = attributes.GetColor(Resource.Styleable.CustomeTitleBar_left_button_text_color, Color.White); title_bar_left_btn.SetTextColor(leftButtonTextColor); } else //(不设置文本,就只能设置图标) { int leftButtonDrawable = attributes.GetResourceId(Resource.Styleable.CustomeTitleBar_left_button_drawable, Resource.Drawable.icon_white_arrow_left); if (leftButtonDrawable != -1) { Drawable drawable = Resources.GetDrawable(leftButtonDrawable); drawable.SetBounds(0, 0, drawable.MinimumWidth,drawable.MinimumHeight);//不设置这句图标显示不出来 title_bar_left_btn.SetCompoundDrawables(drawable,null,null,null); } } //右边按钮 //是否显示 bool rightButtonVisible = attributes.GetBoolean(Resource.Styleable.CustomeTitleBar_right_button_visible, true); if (rightButtonVisible) { title_bar_right_btn.Visibility = ViewStates.Visible; } else { title_bar_right_btn.Visibility = ViewStates.Gone; } //设置左边按钮的文字和图标(二者只能选其一) string rightButtonText = attributes.GetString(Resource.Styleable.CustomeTitleBar_right_button_text); if (!string.IsNullOrEmpty(rightButtonText)) { title_bar_right_btn.Text = rightButtonText; //设置左边按钮的文字颜色 Color leftButtonTextColor = attributes.GetColor(Resource.Styleable.CustomeTitleBar_right_button_text_color, Color.White); title_bar_right_btn.SetTextColor(leftButtonTextColor); } else //(不设置文本,就只能设置图标) { int rightButtonDrawable = attributes.GetResourceId(Resource.Styleable.CustomeTitleBar_right_button_drawable, Resource.Drawable.icon_white_arrow_left); if (rightButtonDrawable != -1) { Drawable drawable = Resources.GetDrawable(rightButtonDrawable); drawable.SetBounds(0,0,drawable.MinimumHeight,drawable.MinimumHeight); title_bar_right_btn.SetCompoundDrawables(null, null,drawable, null); } } //处理标题 string titleText = attributes.GetString(Resource.Styleable.CustomeTitleBar_title_text); if (!string.IsNullOrEmpty(titleText)) { title_bar_title.Text = titleText; } Color color = attributes.GetColor(Resource.Styleable.CustomeTitleBar_title_text_color,Color.White); title_bar_title.SetTextColor(color); attributes.Recycle(); } } catch (Exception ex) { System.Diagnostics.Debug.Write(ex.ToString()); } } //设置事件的监听 public void SetTitleClickListener(IOnClickListener onClickListener) { if (onClickListener != null) { title_bar_left_btn.SetOnClickListener(onClickListener); title_bar_right_btn.SetOnClickListener(onClickListener); } } //获取左边的Button public Button GetTitleBarLeftBtn() { return title_bar_left_btn; } //获取右边的Button public Button GetTitleRightBtn() { return title_bar_right_btn; } //获取标题 public TextView GetTitleBarTitle() { return title_bar_title; } }
(4)使用自定义标题栏,并且自定义属性
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:mview="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <CustomeTitleBar.MyTitleBar android:id="@+id/myTitleBar" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="10dp" mview:title_text="测试标题" mview:right_button_text="" mview:right_button_text_color="@color/color_white" mview:right_button_visible="true" mview:left_button_text="返回"/> <CustomeTitleBar.MyTitleBar android:id="@+id/myTitleBar" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="10dp" mview:title_text="标题2" mview:right_button_text="提交" mview:right_button_text_color="@color/color_white" mview:left_button_text="返回" mview:left_button_text_color="@color/color_white"/> <CustomeTitleBar.MyTitleBar android:id="@+id/myTitleBar" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="10dp" mview:title_text="标题2" mview:right_button_visible="false" mview:left_button_text="返回" mview:left_button_text_color="@color/color_white"/> <CustomeTitleBar.MyTitleBar android:id="@+id/myTitleBar" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="10dp" mview:title_text="标题2" mview:title_background_color="@color/color_red" mview:right_button_text_color="@color/color_white" mview:left_button_text="返回" mview:left_button_text_color="@color/color_red"/></LinearLayout>
上面的代码基本实现了与activity逻辑代码的分离、UI界面要求、可配置自定义属性的要求,可最关键的事件的回调还没写,的确这是最核心的地方,这个自定义标题栏的两个按钮的单击事件最终还是要在activity中去调用。
这个就留着下次再写吧。
如果觉得还有点懵逼的话,看看github:https://github.com/MaChuZhang/Xamarin-Android-Custom-View/tree/master/CustomeTitleBar
作者:张林
标题:xamarin android自定义标题栏(自定义属性、回调事件)
原文地址:http://blog.csdn.net/kebi007/article/details/75365917
转载随意注明出处
- xamarin android自定义标题栏(自定义属性、回调事件)
- Xamarin Android自定义文本框
- Xamarin.Android 自定义 View
- xamarin android自定义spinner
- Android - 自定义标题栏(TitleBar)
- Android:自定义标题栏(titlebar)
- Android--自定义标题栏(TopBar)
- Android 自定义控件 自定义标题栏
- android自定义标题栏progressBar
- Android自定义标题栏
- 自定义android标题栏
- android实现自定义标题栏
- Android自定义标题栏
- Android 自定义标题栏
- Android 自定义标题栏
- Android自定义标题栏
- Android自定义标题栏
- android之自定义标题栏
- PSSQL DEVELOPER连接外部数据库(oracle to oracle)
- go语言资源大全
- Mycat 开发调试环境配置-开启二次开发之路
- 石子归并 【区间DP】 Codevs1048
- 零食供给若认真,愿我天天加班后厂村……
- xamarin android自定义标题栏(自定义属性、回调事件)
- cms内置tomcat版
- eclipse下如何修改字体大小?
- MOOC清华《程序设计基础》第6章:分鱼问题(从E到A递推)
- SOCKET与 线程 完成聊天室 (服务端)
- 产品新人工作中必知的三个步骤
- Lightoj 1011 Marriage Ceremonies(状压dp入门 or km板子)
- C++编译报错: undefined reference to clock_gettime
- 初学msp430