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


二、界面顯示


三、創建程序&主角代碼
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?
下一篇:蘋果為小學生推出編程指南
