C#-Xamarin的Android項目開發(二)——控制項應用

来源:https://www.cnblogs.com/kiba/archive/2019/02/20/10395681.html
-Advertisement-
Play Games

相信我,這不是一篇吐槽文章。。。。 基礎控制項 Android的控制項和控制項樣式非常特別,它是一種內聯特別高的設計模式,換句話說,它是非常爛的設計。。。。 但在這種特別的關係里還是有一定的規律的,下麵我們一起來看看控制項的使用方式。 首先我們定義一個ImageButton,如下: 如上代碼所示,我們定義了 ...


相信我,這不是一篇吐槽文章。。。。

基礎控制項

Android的控制項和控制項樣式非常特別,它是一種內聯特別高的設計模式,換句話說,它是非常爛的設計。。。。

但在這種特別的關係里還是有一定的規律的,下麵我們一起來看看控制項的使用方式。 

首先我們定義一個ImageButton,如下:

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

如上代碼所示,我們定義了ImageButton,並且設置了他的Src地址,該地址指向了一個圖片。

重點,我們來看這句,background="@drawable/btn_weight;背景色指向了一個資源,為什麼用說指向的是個資源呢?因為btn_weight並不是個圖片,而是個XML文件。。。。如下圖:

那麼我們看看btn_weight到底是什麼把。

<?xml version="1.0" encoding="UTF-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/btn_weight_normal" />
    <item android:state_enabled="false" android:drawable="@drawable/btn_weight_disable" />
    <item android:state_pressed="true" android:drawable="@drawable/btn_weight_press" />
    <item android:state_focused="true" android:drawable="@drawable/btn_weight_press" />
    <item android:drawable="@drawable/btn_weight_normal" />
</selector>

如上述代碼所示,btn_weight里設置了按鈕按下時和常規時的背景色。

沒錯,這種設置方法,確實很繞,按鈕按下的事件和背景樣式混在了一起設置,但在Android里,我們只能去適應它。

----------------------------------------------------------------------------------------------------

好了,現在基礎控制項寫完了,有沒有感覺自己從現代化城市回到了農耕社會。。。。

相信我,用Xamarin開發,你在農耕社會還有個犁耙,用AS開發,你會發現你只能用手挖。。。。

GridView

首先,Android的GridView是我見過最奇葩的列表使用方式。。。

然後,我們開始學習使用它把。

先找到GridView控制項,代碼如下:

GridView my_grid = this.FindControl<GridView>("my_grid");

接著,我們定義一個適配器,並把他賦值給GridView的的Adapter屬性,代碼如下:

IListAdapter adapter = new GridAdapter(this, this.Resources);
my_grid.Adapter = adapter;//配置適配器

嗯,這裡看上去代碼還算簡潔,但接下來就不一樣了,讓我們來看看這個奇葩的適配器吧。

首先,我們看下適配器代碼:

public class GridAdapter : BaseAdapter
    {
        private DisplayMetrics localDisplayMetrics;
        private LayoutInflater inflater;
        private Resources resources;
        public GridAdapter(Context context)
        { 
            resources = context.Resources;
            localDisplayMetrics = resources.DisplayMetrics;
            inflater = LayoutInflater.From(context);
        }
        public override int Count => 9; 
        public override Object GetItem(int position)
        {
            return null;
        } 
        public override long GetItemId(int position)
        {
            return position;
        }
        public override View GetView(int paramInt, View paramView, ViewGroup paramViewGroup)
        {
            paramView = inflater.Inflate(Resource.Layout.activity_label_item, null);
            TextView text = (TextView)paramView.FindViewById(Resource.Id.activity_name);
            switch (paramInt)
            {
                case 0:
                    {
                        text.Text = "local";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_local);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
                case 1:
                    {
                        text.Text = "search";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_search);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
                case 2:
                    {
                        text.Text = "checkin";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_checkin);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
                case 3:
                    {
                        text.Text = "promo";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_promo);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
                case 4:
                    {
                        text.Text = "tuan";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_tuan);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }

                case 5:
                    {
                        text.Text = "rank";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_rank);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
                case 6:
                    {
                        text.Text = "history";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_history);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
                case 7:
                    {
                        text.Text = "myzone";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_myzone);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
                case 8:
                    {
                        text.Text = "more";
                        Drawable draw = this.resources.GetDrawable(Resource.Drawable.home_button_more);
                        draw.SetBounds(0, 0, draw.IntrinsicWidth, draw.IntrinsicHeight);
                        text.SetCompoundDrawables(null, draw, null, null);
                        break;
                    }
            }
            paramView.SetMinimumHeight((int)(96.0F * localDisplayMetrics.Density));
            paramView.SetMinimumWidth(((-12 + localDisplayMetrics.WidthPixels) / 3));
            return paramView;
        }
    }

代碼如上所示,適配器的構造函數接受了一個參數,是適配器所屬Activity,主要用於在適配器里調用Activy的信息。

然後我們通過LayoutInflater(佈局填充類),將xml佈局文件實例化為它對應的View對象,以供後續使用。

然後我們重寫BaseAdapter類的一些屬性和方法。

其中重寫的Count屬性需要特別註意,他代表我們列表的顯示數,他是需要賦值的。這裡的事例為其定義了一個常數9。

接下來我們重點看下GetView方法。

GetView這個方法幹了很多事,作為C#開發者,從字面上是很難理解它是乾什麼的;不過我們可以聯想思考,我們暫時把他理解為行的導入事件,這樣就很形象了吧。

因為,至於為什麼會叫GetView,我想,大概是因為他即幹了行綁定數據的事,又幹了行視圖佈局的事,所以沒有更合適的命名,才這麼叫的吧。

這也是為什麼我感覺他奇葩的原因,因為在之前的Activity和佈局中已經混淆了視圖和數據,然後,在控制項里,我們又一次把數據和佈局攪和在了一起。。。。

下麵我們看看它是如何混淆,不,他是如何工作的吧。

首先,在行導入的GetView中,我們找到要填充的佈局XML——activity_label_item.xml。

paramView = inflater.Inflate(Resource.Layout.activity_label_item, null);

接著,我們找這個行佈局內的控制項,然後為他賦值,這裡activity_label_item.xml很簡單,只有一個Textview,也就是說,這裡我們需要做的就是給他賦值。

然後,我們通過paramInt來判斷當前行,正常情況,在這裡找到Activity的數據集合,找到集合的對應行賦值即可了。

Demo里我們做了一下特殊處理,我們為行視圖添加了圖片。

運行結果如下圖:

如圖所示,列表已經創建完成了。

下麵我們為列表添加點擊事件;代碼如下:

my_grid.ItemClick += (s, e) =>
{
    this.ShowToast("Click Me" + e.Id);
};

代碼很簡單,也很簡潔,實現效果如下:

如上圖所示,我們成功的實現了點擊事件。

到此,控制項的基礎應用就講完了,下一篇繼續講解Android軟體的部署。

----------------------------------------------------------------------------------------------------

代碼已經傳到Github上了,歡迎大家下載。

Github地址:https://github.com/kiba518/KibaXamarin_Android

----------------------------------------------------------------------------------------------------

註:此文章為原創,歡迎轉載,請在文章頁面明顯位置給出此文鏈接!
若您覺得這篇文章還不錯,請點擊下右下角的推薦】,非常感謝!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 2.1 資料庫和資料庫表的創建 ①資料庫的創建(在資料庫系統中劃分一塊存儲數據的空間): ②資料庫表的創建 註意: 資料庫 (1)在①中,[ charset 字元集 ] 是可選的,用於設定資料庫的預設字元集,即資料庫存儲使用的字元集。當不聲明時,預設繼承伺服器的字元集 utf-8。 (2)關於字元集 ...
  • 1.安裝 xtrabackup 工具包 下載percona yum源 https://www.percona.com/redir/downloads/percona-release/redhat/percona-release-0.1-4.noarch.rpm 通過 yum 方式安裝 percona ...
  • 本文由雲+社區發表 作者:騰訊雲資料庫 Introduction 導言 任何看到顯著增長的應用程式或網站,最終都需要進行擴展,以適應流量的增加。以確保數據安全性和完整性的方式進行擴展,對於數據驅動的應用程式和網站來說十分重要。人們可能很難預測某個網站或應用程式的流行程度,也很難預測這種流行程度會持續 ...
  • LOGO The tags of features: 開源,記憶體數據存儲,被用作為資料庫,cache and message 中間人/中間件 一個實例:單進程(無子進程),單線程,I/O多路復用( multiplexing and non-blocking I/O)處理客戶端的TCP連接。 支持的數 ...
  • 本文用來介紹Foundation框架的相關知識,以及Foundation框架所提供類的相關知識總結。 1. 框架介紹 框架是由很多類、方法、函數和文檔按照一定的邏輯組織起來的集合,以使開發程式變得更加容易。在OS X系統下有100多個框架,這些框架可以用來開發應用程式。 2. Foundation框 ...
  • Flutter 即學即用系列博客第五彈來了。 自定義 Widget 讓你對 UI 瞭解更加深入。 還有 dart 語法糖
  • 繼該系列的第一篇和番外篇之後,今天我們來聊一聊多視窗開發的註意事項。實際上,與其說“多視窗開發”,不如說讓我們的APP 適應多視窗模式 。 可能有朋友會問,為什麼要提到多視窗模式呢? 這是因為: 1. 摺疊屏在展開後的屏幕會變大,而變大帶來的變化就是多視窗運行; 2. 多視窗模式在很早之前就已經被G ...
  • 本人做安卓開發三個月,不是本專業的(興趣轉行),是一枚萌新,目前公司的項目是一個游戲的腳本,但畢竟一個項目所用到的知識是有限的,所以決定開通博客,堅持每天學習(目前也沒發現好的學習資源,知識比較老)並分享,這幾天將分享公司項目用到的技術同時還有自己學習的東西,請多多指教!!! github後期同步更 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...