我一直在阅读有关如何为Android Xamarin创建某种UserControl
的教程和文章,但由于对这些教程/文章的不良解释,我仍然不清楚如何做到这一点由于缺乏例子。
我需要的是创建一个UserControl
来保存关于商店的一些信息(图片,商店名称,商店地址,商店联系人以及更多细节,但这些应该足以构建一个这里的样本。)
ASCII样本:
+-----------------------------------+
| +----------+ |
| |/ / / / / | STORE NAME |
| | / / / / /| \ |
| |/ / / / / | STORE ADDRESS > |
| | / / / / /| / |
| |/ / / / / | STORE CONTACT |
| +----------+ |
+-----------------------------------+
现在,我将如何在Android Xamarin上构建它?我明白了,从我看过的教程中,我需要一个布局和一个代码隐藏( duh!),但究竟是哪一个 - {{1 }或Activity
?即使在我编辑布局文件时在Visual Studio中,它也会在电话框架中显示布局,这并不代表我构建页面布局而不是Fragment
布局?
Jon Douglas给出了答案,我能够做我想做的事。
我将留下复制我上面提到的布局所需的示例代码和一些解释 - 也许它可以在以后帮助某人。
对于商店按钮列表,我需要创建4个文件:
UserControl
布局模板,它将保留按钮的结构; Button
适配器,其中包含初始化ListView
和事件所需的代码; ListView
,其中将填充商店列表; 虽然我使用片段,但我不认为使用活动的样本之间存在很大差异。
ListView
<?xml version="1.0" encoding="utf-8"?>
<!-- The root of the layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp" >
<!-- Needed to add the elements side-by-side,
for some reason didn't work to me setting
the `orientation` on the root layout -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" >
<!-- The store image -->
<ImageView
android:id="@+id/StoreImage"
android:layout_gravity="top"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="55"
android:paddingTop="0dp" />
<!-- This `LinearLayout` will hold the store name,
address and contact vertically -->
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="100"
android:layout_marginLeft="15px" >
<!-- The store name -->
<TextView
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFDCBB73"
android:id="@+id/StoreName"
android:layout_marginBottom="5dp" />
<!-- The store address -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Store address label -->
<TextView
android:text="@string/AddressText"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#FF9D9D9D"
android:layout_marginRight="5dp" />
<!-- Store address value -->
<TextView
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#FF9D9D9D"
android:textStyle="bold"
android:id="@+id/StoreAddress" />
</LinearLayout>
<!-- The store contact -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Store contact label -->
<TextView
android:text="@string/ContactsText"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#FF9D9D9D"
android:layout_marginRight="5dp" />
<!-- Store contact value -->
<TextView
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#FF9D9D9D"
android:textStyle="bold"
android:id="@+id/StoreContacts" />
</LinearLayout>
</LinearLayout>
<ImageView
android:src="@drawable/arrowright"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="5dp"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:id="@+id/StoreEntry_ViewStore" />
</LinearLayout>
</LinearLayout>
using Android.App;
using Android.Graphics;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Project {
public class ListViewAdapter : BaseAdapter<StoreObject> {
// Properties
private Activity Context {
get; set;
}
private List<StoreObject> StoresList {
get; set;
}
// Methods
public override Int32 Count {
get {
return StoresList.Count;
}
}
public override Int64 GetItemId( Int32 position ) {
return position;
}
public override StoreObject this[ Int32 position ] {
get {
return StoresList[ position ];
}
}
public override View GetView( Int32 position, View convertView, ViewGroup parent ) {
StoreObject
store = StoresList[ position ];
View
view = convertView ?? Context.LayoutInflater.Inflate( Resource.Layout.StoreEntry, null );
// Set the store image
Double
imageWidth = Context.Resources.DisplayMetrics.WidthPixels / Context.Resources.DisplayMetrics.Density * (3.0 / 7.0);
Bitmap
storeBitmap = Utils.GetBitmap( store.Image, (Int32) imageWidth );
view.FindViewById<ImageView>( Resource.Id.StoreImage ).SetImageBitmap( storeBitmap );
// Set the store name
view.FindViewById<TextView>( Resource.Id.StoreName ).SetText( store.Name, TextView.BufferType.Normal );
// Set the store schedule, whether is open or closed
String
storeSchedule = store.isOpen ?
Context.Resources.GetString( Resource.String.OpenText ) :
Context.Resources.GetString( Resource.String.ClosedText );
view.FindViewById<TextView>( Resource.Id.StoreSchedule ).SetText( storeSchedule, TextView.BufferType.Normal );
// Set the store address
String
storeLocation = Context.Resources.GetString( Resource.String.NotAvailableText );
if (store.Address != null) {
storeLocation = store.Address.City;
}
view.FindViewById<TextView>( Resource.Id.StoreAddress ).SetText( storeLocation, TextView.BufferType.Normal );
// Set the store contact
String
storeContact = Context.Resources.GetString( Resource.String.NotAvailableText );
if (store.contacts != null && store.contacts.Count > 0) {
storeContact = store.contacts.FirstOrDefault().PhoneNumber.ToString();
}
view.FindViewById<TextView>( Resource.Id.StoreContacts ).SetText( storeContact, TextView.BufferType.Normal );
return view;
}
// Constructors
public ListViewAdapter( Activity context, List<StoreObject> items ) : base() {
Context = context;
StoresList = items;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/StoresHolder"
android:listSelector="#7FDCBB73" />
我希望这可以帮助将来的某个人。
答案 0 :(得分:1)
看起来您正在创建Listview
或RecyclerView
以根据您的ASCII样本存储“商店”商品列表。
RecyclerView
:http://developer.android.com/training/material/lists-cards.html
如果您需要更多自定义内容,您可以随时制作自己的自定义View
:
http://developer.android.com/guide/topics/ui/custom-components.html
是否进入Activity
或Fragment
;关于何时应该使用其中一个,还有许多其他的SO问题:
答案 1 :(得分:0)
我不知道如何使用Android Xamarin,我认为它类似于Android Studio。在这种情况下,1st认为你要做的是创建一个具有ImageView的LinearLayout和另一个具有三个TextField的LinearLayout。
对于代码隐藏不知道你在问什么,记得把id放在XML代码中的所有元素上以便稍后通过id找到。
答案 2 :(得分:0)
您希望创建Fragment
,除非这些将在列表中。在这种情况下,您将使用RecyclerView
,ViewHolder模式和布局。如果你可以在两者中使用它,那么创建一次布局,你可以将它用作片段的布局和视图持有者布局。
答案 3 :(得分:0)
活动是一个完整页面(布局+代码隐藏)。它总是全屏,但可以具有透明度。
Fragment是一个用户控件(布局+后面的代码)。 您可以在其他活动,另一个片段或代码中使用它。 它可以有任何形状。
创建片段时,编辑器将显示完整的手机视图。但实际上,片段放置的空间由父布局定义,即您添加片段的布局。
您还可以通过继承View类(或任何其他控件)来编写自定义视图。自定义视图始终以代码(无布局)编写。
另一个选择是在布局中使用“include”标记。它在此布局中添加了另一个布局。缺点是所包含的部分没有特定的代码,所有者的代码背后负责使用所包含的内容。
希望它有所帮助。