如何在Android Xamarin

时间:2016-04-06 16:05:23

标签: android xamarin

我一直在阅读有关如何为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

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" />

我希望这可以帮助将来的某个人。

4 个答案:

答案 0 :(得分:1)

看起来您正在创建ListviewRecyclerView以根据您的ASCII样本存储“商店”商品列表。

带有自定义行的

ListViewhttps://developer.xamarin.com/guides/android/user_interface/working_with_listviews_and_adapters/part_3_-_customizing_a_listview's_appearance/#Creating_Custom_Row_Layouts

带有自定义卡片的

RecyclerViewhttp://developer.android.com/training/material/lists-cards.html

如果您需要更多自定义内容,您可以随时制作自己的自定义View

http://developer.android.com/guide/topics/ui/custom-components.html

是否进入ActivityFragment;关于何时应该使用其中一个,还有许多其他的SO问题:

Dilemma: when to use Fragments vs Activities:

答案 1 :(得分:0)

我不知道如何使用Android Xamarin,我认为它类似于Android Studio。在这种情况下,1st认为你要做的是创建一个具有ImageView的LinearLayout和另一个具有三个TextField的LinearLayout。

对于代码隐藏不知道你在问什么,记得把id放在XML代码中的所有元素上以便稍后通过id找到。

答案 2 :(得分:0)

您希望创建Fragment,除非这些将在列表中。在这种情况下,您将使用RecyclerView,ViewHolder模式和布局。如果你可以在两者中使用它,那么创建一次布局,你可以将它用作片段的布局和视图持有者布局。

答案 3 :(得分:0)

活动是一个完整页面(布局+代码隐藏)。它总是全屏,但可以具有透明度。

Fragment是一个用户控件(布局+后面的代码)。 您可以在其他活动,另一个片段或代码中使用它。 它可以有任何形状。

创建片段时,编辑器将显示完整的手机视图。但实际上,片段放置的空间由父布局定义,即您添加片段的布局。

您还可以通过继承View类(或任何其他控件)来编写自定义视图。自定义视图始终以代码(无布局)编写。

另一个选择是在布局中使用“include”标记。它在此布局中添加了另一个布局。缺点是所包含的部分没有特定的代码,所有者的代码背后负责使用所包含的内容。

希望它有所帮助。