在activity_main,我有一個FrameLayout。我想要它,所以當我按下一個按鈕CalcFragment時,那里會彈出一個,當我按下另一個按鈕時,GraphFragment那里會彈出一個。CalcFragment當應用程式第一次啟動時,我也想成為那里的東西。我還沒做GraphFragment,因為我還在努力CalcFragment作業。
當我使用片段而不是 時,我的所有代碼都有效FrameLayout,并手動告訴片段顯示CalcFragment。但是,當我使用 aFrameLayout時,整個應用程式都會崩潰。
這是代碼CalcFragment.java:
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class CalcFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_calc, container, false);
}
}
MainActivity.java這是'sonCreate函式中的代碼段,應該將其CalcFragment放入FrameLayout:
Fragment calcFragment = new CalcFragment();
Fragment graphFragment = new GraphFragment();
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
fragTrans.replace(R.id.frag_container, calcFragment);
fragTrans.addToBackStack(null);
fragTrans.commit();
在那之后的代碼是一組設定所有按鈕功能的代碼CalcFragment。當我嘗試啟動應用程式時,它給了我一個錯誤,基本上說我參考的 UI 元素(片段中的元素)不存在。即使,如果我洗掉代碼,UI 元素顯然確實存在。我猜這是一個膨脹錯誤,由于某種原因,代碼只是無法用主要活動的 UI 元素膨脹片段中的 UI 元素。我想,我真的不知道。我還嘗試將所有這些代碼移到CalcFragment.java onCreate函式中,但這反過來又產生了一系列我什至無法理解的問題。我幾乎不知道片段是如何作業的,我只是在做 2 個 YouTube 教程告訴我的好主意。
請幫忙,我不知道發生了什么。謝謝!
編輯:如果您想查看專案中的任何其他內容,這里是一個谷歌驅動器鏈接。
https://drive.google.com/drive/folders/1E3inSfdbKkTFjX44pWBBRt545rs34C4q?usp=sharing
或者,如果您不想使用 google drive,這里是整個專案的每一行代碼:
MainActivity.java:
package com.example.chrisscalculator2;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.text.*;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import android.view.*;
import java.util.HashMap;
import complexnumbers.*;
//import android.*;
public class MainActivity extends AppCompatActivity {
public static int historyDepth = 100; //how many entries in equation history
public static int clearCount = 0; //how many times we've hit the clear button in a row
public static boolean dotPress = false; //how many times we've hit the . button in a row (false=even, true=odd)
public static boolean ePress = false; //how many times we've hit the e button in a row (false=even, true=odd)
@Override
protected void onCreate(Bundle savedInstanceState) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
getWindow().setNavigationBarColor(Color.parseColor("#000000"));
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//LayoutInflater inflater = getLayoutInflater();
//View graphLayout = inflater.inflate(R.layout.graph_layout, null);
Fragment calcFragment = new CalcFragment();
//Fragment graphFragment = new GraphFragment();
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
fragTrans.replace(R.id.frag_container, calcFragment);
fragTrans.addToBackStack(null);
fragTrans.commit();
final boolean[] secKeys = {false};
EditText calc_inp = (EditText) findViewById(R.id.calc_input);
calc_inp.setShowSoftInputOnFocus(false);
}
}
活動主.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@ id/main_layout"
android:layout_width="1080px"
android:layout_height="2340px"
android:background="#000000"
tools:context=".MainActivity">
<Button
android:id="@ id/graph_button_1"
android:layout_width="240px"
android:layout_height="90px"
android:backgroundTint="#0000FF"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
android:text="Graph"
android:textAllCaps="false"
android:textSize="42px"
app:layout_constraintStart_toEndOf="@ id/equations_button_1"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@ id/calc_button_1"
android:layout_width="240px"
android:layout_height="90px"
android:backgroundTint="#0000FF"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
android:text="Calc"
android:textAllCaps="false"
android:textSize="42px"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@ id/equations_button_1"
android:layout_width="240px"
android:layout_height="90px"
android:backgroundTint="#0000FF"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
android:text="Equations"
android:textAllCaps="false"
android:textSize="42px"
app:layout_constraintStart_toEndOf="@ id/calc_button_1"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@ id/frag_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/equations_button_1"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
這是fragment_calc.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@ id/fragment_calc_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
tools:context=".CalcFragment">
<EditText
android:id="@ id/calc_input"
android:layout_width="0dp"
android:layout_height="135px"
android:layout_marginBottom="30px"
android:background="@drawable/shape"
android:ems="10"
android:inputType="none"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textColor="#00FFFF"
android:textSize="54px"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="SpeakableTextPresentCheck" />
</android.support.constraint.ConstraintLayout>
這是 CalcFragment.java:
package com.example.chrisscalculator2;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class CalcFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_calc, container, false);
}
}
PS我知道我使用的是像素而不是dp。相信我,我有一個非常非常非常非常非常好的理由。
uj5u.com熱心網友回復:
由于我要求的資訊在編輯歷史記錄中,我將向您展示問題所在:
Fragment calcFragment = new CalcFragment();
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
fragTrans.replace(R.id.frag_container, calcFragment);
fragTrans.addToBackStack(null);
fragTrans.commit();
...
EditText calc_inp = (EditText) findViewById(R.id.calc_input);
calc_inp.setShowSoftInputOnFocus(false);
關于Fragments 有一個很大的指南,這里有一個關于事務的重要資訊:
呼叫
commit()不會立即執行事務。相反,事務被安排在主 UI 執行緒上運行,只要它能夠這樣做。但是,如有必要,您可以呼叫commitNow()以立即在您的 UI 執行緒上運行片段事務。請注意,
commitNow與addToBackStack.commit()或者,您可以通過呼叫執行尚未運行的呼叫提交的所有掛起的 FragmentTransactionsexecutePendingTransactions()。這種方法與addToBackStack.
因此,當您呼叫時commit(),Fragment實際上還沒有添加 - 它稍后會發生。如果您立即呼叫supportFragmentManager.getFragments(),您將得到一個空串列,因為尚未添加片段。
如果您立即呼叫supportFragmentManager.executePendingTransactions(),Fragment 則會添加 s,并將其顯示在Fragments 串列中。
但這不是你唯一的問題——僅僅因為片段已經被添加,它的視圖(即它的布局層次結構)還沒有被膨脹。片段有自己的生命周期 -onCreate等onCreateView,它們必須運行,并且在構建一個并將其添加到您FragmentManager的之后立即,它還沒有處于CREATED狀態。
這意味著您不能這樣做findViewById(您在Activity' 的布局上運行),因為Fragment' 的視圖(其布局層次結構)尚未膨脹,因此整體布局中尚不存在具有該 ID 的視圖。它會在以后發生。我對此含糊其辭,因為如果不連接到 Fragment 以檢查它何時準備就緒或其他類似的復雜事情,您無法確定確切的時間。
并且因為Activities和Fragments有自己獨立的生命周期,并且它們可以以任何順序獨立地重新創建(例如,當您旋轉螢屏并且一切都被破壞時),您甚至無法確定哪個會準備好。你可以觀察Lifecycle物體,但是......你根本不需要這樣做,它非常先進 - 特別是當你只想顯示一個片段時,最基本的東西。
如果這聽起來很復雜,是的 - 這就是創建導航組件的部分原因,因此開發人員不必擔心很多這些東西。但在這種情況下,最簡單的方法是將事物分開 -Activity不需要知道何時創建 的視圖。您應該能夠只添加片段并讓它作業。所以這:Fragment
calc_inp.setShowSoftInputOnFocus(false);
可以進入Fragment's設定,onCreate或者其他什么。這是 Fragment 自身初始化的一部分,對吧?讓它處理自己的事情,連接自己的視圖和聽眾,并按照它們應該作業的方式進行設定。這樣,您只需將 aFragment放入 an 中Activity,它就可以正常作業 -Activity無需在其中四處尋找即可完成設定。
(在某些情況下,您可能需要連接一些東西以便ActivityandFragment可以通信 - 但這是其中之一嗎?Activity需要在這里參與嗎?這就是您需要的心態 - 讓您Fragment的 s 獨立盡可能Activity簡單,盡可能簡單。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/514032.html
標籤:安卓安卓片段
