主頁 > 移動端開發 > 移動終端應用開發上機2常用控制元件和事件處理

移動終端應用開發上機2常用控制元件和事件處理

2021-10-09 08:49:13 移動端開發

一、題目:界面設計,

(1)開發一個單頁面的APP,
(2)“線性布局”TAB頁:顯示個人相關資訊,需要使用TextView、EditText、Button、CheckBox等控制元件,(頁面內容也可自行設計)
(3)“觸摸屏處理”TAB頁:在規定區域內實作觸摸屏功能,
(4)其他TAB頁:可自行設計頁面功能,
界面示意圖1輸入選擇確定
界面示意圖2觸摸事件

二、界面顯示

界面1
界面2

三、創建程序&主角代碼

1、工程創建
file->new->new project->Tabbed Activity

2、觀察里面的工程內容,會發現里面有幾個需要我們注意的東西,

我們知道Tab頁面可以分出好幾個,而老師或者一些很老的博客里面會告訴我們,若是我們需要n個Tab頁面,我們則需要在一個project中新建n個fragmentactivity的Java檔案和xml檔案,
但是在這個project里面我們只看到了一個fragment.xml檔案,而在運行模擬器時卻發現有兩個Tab,


3、這時回傳去看代碼,在ui.main檔案夾下我們找到了一個名為SectionsPagerAdapter的Java檔案,

這個檔案很重要,因為其內包含了Tab的標題、Tab的內容等代碼,這也恰恰表明,此次制作Tab的主角就是SectionsPagerAdapter.java,
但是在對它“動手”之前,請先在布局檔案中新建兩個布局檔案,在這里,用紅框框的第一個檔案是我的第一個Tab,第二個檔案是第二個Tab,

拿來主義,上課時錄了個視頻,把老師在PPT上展示的代碼直接敲下來用了,所以第一個xml檔案用的還是老師上課展示的代碼,
第二個xml檔案里用的是書上的代碼,
因為不是這次的重點,這里就不放了,主要用到的還是布局嵌套,按鍵用的是RadioButton,

4、開始看主角檔案里的代碼,

直接用它封裝好的工程的好處就是有的地方有注釋,還能省許多心,
從上圖的注釋中,我們可以知道這個名字叫FragmentPagerAdapter的東西(類)可以回傳與某個部分/分欄/頁對應的片段,
這里的Tab有兩個,用了個陣列(也許?)來定義它們,我改了改名字,
改名字可以在上面圖片的陣列里面改,如果會報錯的話,也可以在res->values->string.xml修改相應的Tab名字,因為這里Tab的標題名字就是源自于string.xml檔案里的,代碼引數為:new int[]{R.layout.Tab1,R.layout.Tab2},

而這個getItem則是定位用的(如果我沒猜錯的話),它可以根據Tab不同位置呈現不同的內容,
所以等會需要在這里修改回傳內容,

后面還有兩段代碼不是我們重點要關注的地方,可以暫時不用管(如果不需要自行車的話),

5、在這里,我們利用getItem去獲取我們要顯示的頁面,把return后回傳的內容刪掉,用switch去回傳我們需要的頁面,頁面內容在Tab1和Tab2里,

    @Override
        //根據tab不同位置呈現不同的內容
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        public Fragment getItem(int position) {
            switch (position){
                case 0:
                    return new Tab1();
                case 1:
                    return new Tab2();
            }
            return null;
        }

然后建立一個靜態類頁面,其父類是Fragment,

public static class Tab1 extends Fragment
{
	//內容
}

接下來就可以往這個類里放我們要的東西了,在這里寫下的代碼是直接用于頁面上的,
在這里我直接挪用了老師的代碼,

 public static class Tab1 extends Fragment {
        public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            View v = inflater.inflate(R.layout.section_pager_adapter, container, false);
            final RadioButton rb1 = (RadioButton) v.findViewById(R.id.RadioButton1);
            final RadioButton rb2 = (RadioButton) v.findViewById(R.id.RadioButton2);

            final EditText ed1 = (EditText) v.findViewById(R.id.entry1);
            final EditText ed2 = (EditText) v.findViewById(R.id.entry2);

            final TextView text1 = (TextView) v.findViewById(R.id.label4);
            Button but1 = (Button) v.findViewById(R.id.get);
            Button but2 = (Button) v.findViewById(R.id.cancel);
            final String str3="";
            but1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String str1 = ed1.getText().toString();
                    String str2 = ed2.getText().toString();
                    String str3 = null;
                    if(rb1.isChecked())
                        str3=rb1.getText().toString();
                    if(rb2.isChecked())
                        str3=rb2.getText().toString();
                    text1.setText("姓名:"+str1+"   年齡:"+str2+"   是否現在睡覺:"+str3);
                }
            });
            but2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ed1.setText("");
                    ed2.setText("");
                    rb1.setChecked(false);
                    rb2.setChecked(false);
                }
            });
            return v;
        }
    }

在這里實體化的兩個button是用來作“獲取”和“清除”作用的,代碼內容和我上一篇上機的博客差不多,在此不做贅述,
重點是這行代碼,

View v = inflater.inflate(R.layout.section_pager_adapter, container, false);

然后照著Tab1的樣子建立一個Tab2,這里的Tab2頁面內容是書上的一個觸摸事件(touch event),
需要用到MotionEvent的包,重寫里也要像Tab1一樣加上LayoutInflater和ViewGroup容器,還有重寫方法… …代碼不難,花兩分鐘多看兩眼基本能知道是什么了,

public static class Tab2 extends Fragment{
		@SuppressLint("ClickableViewAccessibility")
        @Override
        public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            TextView labelView = null;
            View v = inflater.inflate(R.layout.touch_event, container, false);
            labelView = (TextView) v.findViewById(R.id.event_label);
            TextView touchView = (TextView)v.findViewById(R.id.touch_area);
            final TextView historyView = (TextView)v.findViewById(R.id.history_label);


            TextView finalLabelView = labelView;
            touchView.setOnTouchListener(new View.OnTouchListener()
            {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    int action = event.getAction();
                    switch (action) {
                        case (MotionEvent.ACTION_DOWN):
                            Display("ACTION_DOWN",event);
                            break;
                        case (MotionEvent.ACTION_UP):
                            int historySize = ProcessHistory(event);
                            historyView.setText("歷史資料量:"+historySize);
                            Display("ACTION_UP",event);
                            break;
                        case (MotionEvent.ACTION_MOVE):
                            Display("ACTION_MOVE",event);
                            break;
                    }
                    return true;
                }
            private void Display(String eventType, MotionEvent event){
            int x = (int)event.getX();
            int y = (int)event.getY();
            float pressure = event.getPressure();
            float size = event.getSize();
            int RawX = (int)event.getRawX();
            int RawY = (int)event.getRawY();

            String msg = "";
            msg += "事件型別:" + eventType + "\n";
            msg += "相對坐標:"+String.valueOf(x)+","+String.valueOf(y)+"\n";
            msg += "絕對坐標:"+String.valueOf(RawX)+","+String.valueOf(RawY)+"\n";
            msg += "觸點壓力:"+String.valueOf(pressure)+",  ";
            msg += "觸點尺寸:"+String.valueOf(size)+"\n";
            finalLabelView.setText(msg);
        }
            private int ProcessHistory(MotionEvent event)
            {
                int historySize = event.getHistorySize();
                for (int i = 0; i < historySize; i++) {
                    long time = event.getHistoricalEventTime(i);
                    float pressure = event.getHistoricalPressure(i);
                    float x = event.getHistoricalX(i);
                    float y = event.getHistoricalY(i);
                    float size = event.getHistoricalSize(i);
                }
                return historySize;
            }
            });
            return v;
        }
    }

其實在一開始的時候我的代碼會顯示出高亮的一塊黃色,像下面這樣,

很迷茫,在網上找了也只有一個答案“代碼寫得不規范導致”,但是怎么改呢?完全沒有解決方案,雖然也能夠運行,但是看著很難受… …
后來當我因為另一個problem一籌莫展的時候,不小心點到了頁面的某個地方,它給我自動添加了一行代碼,我的代碼終于恢復正常了,

添加了這行代碼:

@SuppressLint("ClickableViewAccessibility")

后來去網上找了才知道是什么問題,在文章結尾會附上相關鏈接,

四、觀察MainActivity.java里的代碼


在一開始運行模擬器的時候發現頁面右下角有一個懸浮視窗,點擊其視窗會出現彈窗文字,

其監聽器在MainActivity.java檔案中,因為只是了解,并沒有過多深究,所以只是改了其文本內容,
但是這個檔案里的內容很重要,因為其控制了我們整個工程的頁面,

五、演示




注:因為是在模擬器上跑的代碼,用的是滑鼠點擊“螢屏”,所以這里的觸點壓力和觸點尺寸分別恒為1.0和0.0,

六、小結

只能說,這次的上機很坎坷,因為在一開始,是想要按部就班地抄書上的代碼,然后就好了,但是沒想到書上的代碼有的函式在AndroidStudio里已經失效了,運行時工程直接閃退,于是開始去網上找方法看看能不能改用別的方法去運行這個工程,但是沒想到,這一找,就踏上了Android開發的坎坷之路,
當時去網上找官網,發現這些函式其實已經失效了
失效了

結果跳轉到官網的另外一個頁面,它叫我用navigation… …我不死心,我就去網上找例程,找之前在圖書館借的書里的隨書代碼… …
跑了幾個很炫酷的例程,但我仍然對Fragment這個東西一無所知,
抄的例程
跑的例程
跑的例程

而就在10月5日,也就是三天前,我閑得無聊,新建工程的時候發現在工程樣式最下面有一個名為“Tabbed Activity”的樣式,
喜出望外,遂新建工程,
毫無進展,因為看不懂代碼,怎么沒有fragmenta、fragmentb就能夠創建出兩個頁面了?怎么這個MainActivity里面什么東西也沒有?
然后又是漫長地尋找代碼含義的道路,
終于,我在我的收藏夾里找到一個極具關鍵性的博客,是的,這篇博客給我接下來的代碼提供了關鍵,
我終于知道Fragment是什么了!原來在Android升級之后,Fragment被改變成了一個類,但是因為不是Activity這樣的類,所以我們不能直接使用findViewbyId去尋找我們布局檔案里的控制元件,而需要構造一個LayoutInflater方法去構建一個view,雖然這個老師在上課也講過,但是當時的我懵懵懂懂,而且第二天就是國慶了,我的心早已經放假了,

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

而在繼承Fragment父類時,要先匯入以上類,
然后就開始啃代碼,寫代碼了,
這次的上機2我用了6天的時間終于寫完,而這篇博客,我花了兩天的時間寫完,其中的苦難不言而喻,

七、參考

以下這些鏈接是我在這次上機內容中參考過的網站或博客,
ActionBar

Navigation Editor

Android架構組件-Navigation的使用(一)

Tabbed Activity的使用(Fragment)

使用 ViewPager2 創建包含標簽的滑動視圖

Navigation導航圖

Android Studio開發學習(十三)——Fragment

android studio有時寫著代碼,突然某一塊代碼背景變成土黃色

回應觸摸事件

在安卓開發中,我需要將AppCompatActivity 轉換fragment,請問該如何更改

Issue id: ClickableViewAccessibility

【Android】inflater的作用

使用TAB和新的工具列(APPCOMPAT V7-21)

navigation/Menu1Fragment.kt

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/306465.html

標籤:其他

上一篇:《Flutter開發從入門到實戰》:為什么要學Flutter?

下一篇:蘋果為小學生推出編程指南

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more