在activity_main
中,我有一个FrameLayout
。我希望当我按下一个按钮时,一个CalcFragment
会弹出,当我按下另一个按钮时,一个GraphFragment
会弹出。我还希望CalcFragment
是应用程序第一次启动时出现的东西。我还没有创建GraphFragment
,因为我还在努力使CalcFragment
正常工作。
当我使用一个片段而不是FrameLayout
,并手动告诉片段显示CalcFragment
时,我的所有代码都能正常工作。
下面是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
的onCreate
函数中的一段代码,它被假定为将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元素显然是存在的。我猜这是一个膨胀错误,并且由于某种原因,代码在使用main Activity中的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);
}
}
我知道我用的是像素而不是dp。相信我,我有一个非常非常非常非常非常非常好的理由。
1条答案
按热度按时间dsekswqp1#
由于我要求的信息在编辑历史记录中,我将向您说明问题所在:
关于
Fragment
有一个很大的指南,这里有一个关于事务的重要信息:呼叫
commit()
**不会立即执行交易。相反,交易会排定在主UI执行绪上执行,只要它能够执行即可。**不过,如有必要,您可以呼叫commitNow()
,立即在UI执行绪上执行片段交易。请注意,
commitNow
与addToBackStack
不兼容。或者,您可以通过调用executePendingTransactions()
来执行由尚未运行的commit()
调用提交的所有挂起的FragmentTransactions。此方法与addToBackStack
兼容。因此,当你调用
commit()
时,Fragment
实际上还没有被添加--它发生在 * 之后 *。如果你立即调用supportFragmentManager.getFragments()
,你会得到一个空列表,因为这个片段还没有被添加。如果你立即调用
supportFragmentManager.executePendingTransactions()
,那么Fragment
* 将被添加,并且它将出现在Fragment
的列表中。但这并不是你唯一的问题--仅仅因为片段已经被添加,它的 * 视图 *(即它的布局层次结构)还没有膨胀。片段有它们自己的生命周期--
onCreate
,onCreateView
等,它们必须经历这些生命周期,并且在构建一个片段并将其添加到FragmentManager
之后,它还没有处于CREATED
状态。这意味着你不能做
findViewById
(您在Activity
的布局上运行),因为Fragment
的视图(它的布局层次结构)还没有膨胀,所以在整个布局中还没有具有该ID的视图。这将在 * 以后 * 发生。我对这一点含糊其辞,因为你不能确定确切的时间,而无需连接到碎片中检查它何时准备好,或者其他类似的复杂事情。而且,由于
Activities
和Fragments
具有各自独立的生命周期,因此可以按任意顺序独立地重新创建它们(例如,当你旋转屏幕时,所有的东西都被破坏了),你甚至不能确定什么时候哪个会准备好。你可以观察Lifecycle
对象,但是......你根本不需要这样做,它非常高级--尤其是当您只想显示一个Fragment(最基本的东西)时。如果这听起来很复杂的话,是的--这就是为什么要创建 Navigation 组件的部分原因,这样开发人员就不必担心很多这样的事情了。但是在这种情况下,最简单的方法是将事情分开--
Activity
不应该 * 需要 * 知道Fragment
的视图是什么时候创建的。你应该只需要添加Fragment就可以让它工作了。所以这样:可以进入 *
Fragment
的 * 设置,onCreate
或其他什么。它是Fragment自己初始化的一部分,对吗?让它处理自己的事务,连接自己的视图和侦听器,并设置它们应该如何工作。这样,您只需将Fragment
放入Activity
中,它就可以正常工作-Activity
不需要在那里四处走动来完成设置。(有些情况下,您可能需要连接一些东西,以便
Activity
和Fragment
能够通信-但这是其中之一吗?这里需要涉及Activity
吗?这是您需要的心态-使您的Fragment
尽可能独立,并使您的Activity
尽可能简单。)