C#-Xamarin的Android项目开发(一)——创建项目
创建项目
使用xamarin开发安卓项目,首先需要安装vs2017以上版本。因为vs2017以上的版本,可以直接创建xamarin项目。
另外用xamarin开发安卓项目,还需要使用intel的cpu,并且得是双核以上的cpu,因为调试时,需要使用电脑的虚拟化,奔腾4之类的cpu是不支持虚拟化的。
下面我们创建kibaxamarin_android项目,如下图:
点击确定后,会弹出一个选择模板的窗体,这里我们选择一个空白应用,并且选择最小安卓版本号为4.4,如下图:
点击ok后,项目创建完成,解决方案内容如下图
解决方案中重要的文件及文件夹如下:
resources/layout/activity_main.axml:该文件为主页面。
mainactivity.cs:该文件为主页面对应的后台页面,也我们进行逻辑操作或者调用逻辑操作的地方。
resources/value/xxx.xml:value文件夹下主要存储常用的值,类似于我们c#中的const常量。
其他文件夹及文件暂时忽略。
在resources文件夹里,我们可以发现,没有存储图片的地方,那么,我们创建一个文件夹drawable用来存储图片。
为什么用drawable存图片?答案很简单,因为网上的开源样式里的图片大多放在了drawable里,建立一个这样的文件夹,绝对会减少我们的工作量。
接下来,我们看一下我们的核心文件,mainactivity,代码如下:
[activity(label = "@string/app_name", theme = "@style/apptheme", mainlauncher = true)]
public class mainactivity : appcompatactivity
{
protected override void oncreate(bundle savedinstancestate)
{
base.oncreate(savedinstancestate);
// set our view from the "main" layout resource
setcontentview(resource.layout.activity_main);
}
}
首先,我们看第一行的特性,这里有三个属性赋值,含义如下:
label:页面的标题。
theme:页面的样式。
mainlauncher:是否是主窗体,该属性在项目只能给一个页面。
然后,我们可以看到我们的主页面mainactivity继承了appcompatactivity,这里的appcompatactivity是一个继承了activity的子类,我们暂时先不了解它,因为我们即将创建一个继承activity的baseactivity,后续的[activity]也将继承baseactivity。
接下来我们看到了oncreate方法,这里我们需要了解下activity的生命周期,oncreate是activity的第一个触发的方法,可以暂时先理解为activity的构造函数。
oncreate方法里我们看到了setcontentview(resource.layout.activity_main),根据字面我们先简单的理解该方法为设置内容视图。
可以看到我们在设置内容视图的时候,去资源里找了一个页面;也就是说,在android中,视图是倒装的,现有activity然后由activity来控制要导入那个页面视图显示。
为了更好的寻找视图,我们将视图名和活动名进行统一,修改页面的名为mainactivity,然后再重新设置内容视图。(这里有个编译器的bug,我们改名以后,编译器并没有同步,所以我们需要清理一下,再重新生成,如果还不成功,就删除obj文件夹,再重新生成)
baseactivity
通过上面的描述,我们初步了解了xamarin的android项目。
现在我们一起创建一个baseactivity。
首先我们需要为baseactivity封装一些提示信息的方法,让继承该类的活动可以更简单的调用提示。
然后我们封装寻找资源的方法;在android项目里是由活动调用视图,即先有活动后有视图,所以在活动里找页面的控件也是倒装的,那么这个寻找控件的方法就相对代码会比较多,所以我们简单封装一下。
接下来我们在封装一些跳转活动、创建服务、异步调用等基础方法;baseactivity代码如下:
[activity(label = "kibaxamarin_android")]
public class baseactivity : activity
{
public void showactivity<t>() where t : activity
{
intent intent = new intent(this, typeof(t));
startactivity(intent);
}
public void openservice<t>() where t : service
{
intent intent = new intent(this, typeof(t));
startservice(intent);
}
#region 各种提示信息
public void showtoast(string msg)
{
toast.maketext(this, msg, toastlength.short).show();
}
private alertdialog dialog;
public alertdialog initdialog(string msg, action<alertdialog> comfirmcallback, action<alertdialog> cancelcallback)
{
alertdialog cdialog;
//构造器
alertdialog.builder builder = new alertdialog.builder(this);
//标题
builder.settitle("提示");
//图标
//builder.seticon(android.r.drawable.btn_dialog);
//内容
builder.setmessage(msg);
//setpositivebutton(表示按钮的文本,表示单击按钮触发单击事件)
builder.setpositivebutton("ok", new eventhandler<dialogclickeventargs>((s, e) =>
{
if (comfirmcallback != null)
{
comfirmcallback(dialog);
}
}));
builder.setnegativebutton("cancel", new eventhandler<dialogclickeventargs>((s, e) =>
{
if (cancelcallback != null)
{
cancelcallback(dialog);
}
}));
//builder.setneutralbutton("稍后提醒", new eventhandler<dialogclickeventargs>((s, e) => { }));
cdialog = builder.create();//构建dialog对象
return cdialog;
}
public void showalert(string msg, action<alertdialog> comfirmcallback = null, action<alertdialog> cancelcallback = null)
{
if (comfirmcallback == null)
{
cancelcallback = (d) => { dialog.dismiss(); };
}
if (cancelcallback == null)
{
cancelcallback = (d) => { dialog.dismiss(); };
}
dialog = initdialog(msg, comfirmcallback, cancelcallback);
if (dialog != null && !dialog.isshowing)
{
dialog.show();
}
}
public void notifymessage(string message, string title = "消息")
{
notificationmanager manager = (notificationmanager)getsystemservice(context.notificationservice); // 在android进行通知处理,首先需要重系统哪里获得通知管理器notificationmanager,它是一个系统service。
pendingintent pendingintent = pendingintent.getactivity(this, 0,
new intent(this, typeof(mainactivity)), 0);
notification notify1 = new notification();
notify1.icon = resource.drawable.logo;
notify1.tickertext = javestring("您有新短消息,请注意查收!");
notify1.when = datetime.now.tofiletime();
notify1.setlatesteventinfo(this, title, message, pendingintent);
notify1.number = 1;
notify1.flags |= notificationflags.autocancel; // flag_auto_cancel表明当通知被用户点击时,通知将被清除。
// 通过通知管理器来发起通知。如果id不同,则每click,在statu那里增加一个提示
manager.notify(1, notify1);
}
public static java.lang.string javestring(string str)
{
return new java.lang.string("您有新短消息,请注意查收!");
}
#endregion
#region 寻找资源
public t findcontrol<t>(string name) where t : view
{
return findviewbyid<t>(getcode(name));
}
public t findcontrol<t>(string name, action callback) where t : view
{
view view = findviewbyid<t>(getcode(name));
view.click += (s, e) =>
{
callback();
};
return findviewbyid<t>(getcode(name));
}
public int getcode(string name)
{
var r = this.resources;
var code = (typeof(resource.id)).getfields().firstordefault(f => f.name == name).getvalue(r);
return (int)code;
}
#endregion
#region 异步调用
public void asyncload(action action)
{
iasyncresult result = action.begininvoke((iar) =>
{
}, null);
}
public void asyncload(action action, action callback)
{
iasyncresult result = action.begininvoke((iar) =>
{
this.runonuithread(callback);
}, null);
}
public void asyncload<t>(action<t> action, t para, action callback)
{
iasyncresult result = action.begininvoke(para, (iar) =>
{
this.runonuithread(callback);
}, null);
}
public void runonui(action action)
{
((baseactivity)this).runonuithread(() => { action(); });//回ui线程
}
#endregion
#region 获取数据
public void getrest(string url, action<jsonvalue> callback)
{
task.run(() =>
{
try
{
httpwebrequest request = (httpwebrequest)httpwebrequest.create(new uri(url));
request.contenttype = "application/json";
request.method = "get";
using (webresponse response = request.getresponse())
{
using (stream stream = response.getresponsestream())
{
jsonvalue jsondoc = jsonobject.load(stream);
callback(jsondoc);
}
}
}
catch (exception ex)
{
log.debug("baseactivity", $"exception at getrest" + ex.message);
}
});
}
#endregion
}
视图mainactivity.axml
android视图是有xml语法来编写的,其中一些语法定义是很奇葩,但也只能去适应,没有别的办法。比如android里定义id名是这样的:android:id="@+id/btn_search"。我每次看这个@+id都感觉很奇葩,哈哈。
xamarin的视图和android的视图是一样的,所以我们尽可上网找一些资源来使用。
我们先修改视图代码如下:
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff">
<linearlayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/title_background"
android:paddingleft="5dip"
android:paddingright="5dip"
android:paddingtop="5dip"
android:paddingbottom="5dip"
android:gravity="center_vertical">
<linearlayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2">
<textview
android:textappearance="?android:textappearancemedium"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="kibaxamarin_android"
android:textcolor="#ffffffff" />
<imageview
android:src="@drawable/ic_arrow_down"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textcolor="#ffffffff" />
</linearlayout>
<framelayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="5">
<imagebutton
android:src="@drawable/toolbar_upload_photo_normal"
android:layout_gravity="right|center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/btn_weight" />
</framelayout>
</linearlayout>
<linearlayout
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/search_bar_background"
android:padding="6.0dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<button
android:textappearance="?android:textappearancemedium"
android:gravity="left|center"
android:id="@+id/btn_search"
android:layout_width="0.0dip"
android:layout_height="wrap_content"
android:hint="\u0020click me"
android:drawableleft="@drawable/ic_btn_search"
android:layout_weight="1.0" />
</linearlayout>
<gridview
android:paddingtop="20dip"
android:gravity="center"
android:id="@+id/my_grid"
android:layout_width="fill_parent"
android:layout_height="0.0px"
android:layout_margintop="0.0dip"
android:horizontalspacing="10.0dip"
android:verticalspacing="20.0dip"
android:stretchmode="columnwidth"
android:columnwidth="60.0dip"
android:numcolumns="3"
android:layout_weight="1.0"
style="@style/customgridview" />
</linearlayout>
xamarin的简单应用
现在,我们的页面和baseactivity已经完成,让我们一起做一些简单的使用把。
protected override void oncreate(bundle savedinstancestate)
{
base.oncreate(savedinstancestate);
setcontentview(resource.layout.mainactivity);
button btn_search = this.findcontrol<button>("btn_search");
btn_search.click += (s, e) =>
{
this.showtoast("click me");
};
}
如上代码所示,我们找到了button-btn_search,并为他创建了单击事件;看起来还不错,代码还算简洁。
因为baseactivity里寻找控件的方法里,还封装了click方法,所以我们还可以这样使用:
button btn_search = this.findcontrol<button>("btn_search", () => { this.showtoast("click me"); });
xamarin的调试
xamarin的调试非常简单,只要配置好模拟器按f5调试就可以了,因为vs2017集成了emulator模拟器,所以我们只要运行调试,就会自动帮我们启动模拟器。
模拟器是配置很简单,在工具里找到android—android设备管理器,如下图:
然后做一些简单配置修改,如下图:
模拟器配置好以后,在调试启动的选项中,就会增加这个模拟器的选项,如下图:
接下来就很简单了,只要直接点击运行就可以了。
运行结果如下图:
从图中我们可以看到,我们的安装项目已经成功运行了,并且执行了点击事件。
到此,这个简单的安卓项目已经创建完成了,下一篇文章,将介绍xamarin中如何使用安卓控件。
----------------------------------------------------------------------------------------------------
代码已经传到github上了,欢迎大家下载。
github地址:https://github.com/kiba518/kibaxamarin_android
----------------------------------------------------------------------------------------------------
注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错,请点击下右下角的【推荐】,非常感谢!
上一篇: 移动端视频h5表现问题汇总
推荐阅读
-
创建基于ASP.NET core 3.1 的RazorPagesMovie项目(一)-创建和使用默认的模板
-
探讨:android项目开发 统筹兼顾 需要考虑的因素
-
JAVA WEB快速入门之从编写一个基于SpringBoot+Mybatis快速创建的REST API项目了解SpringBoot、SpringMVC REST API、Mybatis等相关知识
-
分享一个基于Net Core 3.1开发的模块化的项目
-
【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 完善
-
Xcode中iOS应用开发的一般项目目录结构和流程简介
-
Android开发之在Android项目里集成调用支付宝支付开发的代码实现
-
Android开发导入项目报错Ignoring InnerClasses attribute for an anonymous inner class的解决办法
-
Android开发之规划项目结构的实例
-
用Eclipse搭建Android开发环境并创建第一个Android项目(eclipse+android sdk)