我已经看到了两个在应用程序中实例化新Fragment的一般实践:
Fragment newFragment = new MyFragment();
Run Code Online (Sandbox Code Playgroud)
和
Fragment newFragment = MyFragment.newInstance();
Run Code Online (Sandbox Code Playgroud)
第二个选项使用静态方法newInstance(),通常包含以下方法.
public static Fragment newInstance()
{
MyFragment myFragment = new MyFragment();
return myFragment;
}
Run Code Online (Sandbox Code Playgroud)
起初,我认为主要的好处是我可以重载newInstance()方法以在创建Fragment的新实例时提供灵活性 - 但我也可以通过为Fragment创建重载构造函数来实现这一点.
我错过了什么?
一种方法比另一种方法有什么好处?还是只是好习惯?
我有一个Fragment带有多个参数的构造函数.我的应用程序在开发期间工作正常,但在生产中我的用户有时会看到此崩溃:
android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment
make sure class name exists, is public, and has an empty constructor that is public
Run Code Online (Sandbox Code Playgroud)
我可以创建一个空的构造函数,因为这个错误消息建议,但这对我没有意义,因为那时我将不得不调用一个单独的方法来完成设置Fragment.
我很好奇为什么这种崩溃偶尔会发生.也许我使用ViewPager不正确?我Fragment自己实例化所有s并将它们保存在一个列表中Activity.我不使用FragmentManager事务,因为ViewPager我看到的例子并不需要它,并且一切似乎都在开发期间工作.
我有一个Activity用的Fragment.我只是想将一个对象传递Activity给它Fragment.
我怎么能这样做?到目前为止我见过的所有教程都是从资源中检索数据的.
编辑:
让我们更精确一点:
我的活动ListView在左侧部分有一个.单击它时,想法是Fragment在右侧部分加载.
当我输入这个时Activity,一个对象Category通过Intent.此对象包含其他对象的列表Questions(包含字符串列表).这些Questions对象显示在ListView上.当我点击其中的一个项目时ListView,我想将列表显示String到Fragment(进入a ListView)中.
要做到这一点,setContentView()我Activity用布局调用我的.在此布局中定义了Fragment要调用的正确类.当我调用它时setContentView(),调用onCreateView()my Fragment,但此时getArguments()返回null.
我怎么能设法在电话会议之前填写onCreateView()?(告诉我,如果我不够清楚)
谢谢
我想启动一个带有自定义布局的对话框,我已经通过DialogFragment实现了该对话框.(我基本上只是改变了onCreateView()并添加了按钮处理程序).该对话框允许用户快速更改重要设置.
该对话框将从几个不同的活动中启动.不同的活动没有太多共同之处,只是在用户更改设置后需要刷新.他们不需要从对话中获取任何信息; 他们只需要知道何时关闭(被解雇).
我尝试在onResume()中刷新活动,但启动和解除对话框似乎永远不会调用此方法.(所以我不确定它为什么会存在,但这可能是另一个问题的主题.)
接下来,我尝试在对话框中添加DialogInterface.OnDismissListener:
public static void showMyDialog(OnDismissListener listener, Activity activity)
{
DialogFragment fragment = new MyDialogFragment();
fragment.show(activity.getFragmentManager(), "date");
activity.getFragmentManager().executePendingTransactions();//A
fragment.getDialog().setOnDismissListener(listener);//B
}
Run Code Online (Sandbox Code Playgroud)
当我最初省略A行时,我在B行得到了NullPointerException,因为此时对话框为null.根据这个SO答案的建议,我调用了executePendingTransaction().这会在B行导致IllegalStateException,并且消息"OnDismissListener已被DialogFragment占用,无法替换." 我也尝试在调用show()之前放入setOnDismissListener(),但这总是导致NullPointerException.
然后我读了另一个SO答案,其中说原始提问者"在DialogFragment的生命周期中过早地调用getDialog()." 所以我尝试在DialogFragment中添加一个构造函数:
public MyDialogFragment(SomeCallback illTakeAnythingICanGet)
{
//I'll store the callback here and call it later
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,添加一个构造函数让Android Lint发出致命的警告,当我查了一下时,我在这个问题中发现了一条评论,似乎说这种方法会让对话无法处理用户在对话框中旋转屏幕开了.
如果用户旋转屏幕,当DialogFragment关闭(被解雇)的方式不会破坏我的应用程序时,活动如何计算?我应该在DialogFragment之外使用其他东西吗?
我有一个包含多个片段的活动.Activity最初有片段,里面有两个按钮.单击此按钮后,我必须用新片段替换片段.每个片段都有各种小部件,并将当前片段替换为各种事件.
这是我的问题.我怎样才能做到这一点.
建议我的想法.
为什么建议(不同的来源)不要为Fragments 重载构造函数,而是使用static Fragment.newInstance()传递Bundle给它?
重载构造函数时,只需显式定义默认值即可.比如果你Fragment因为某些原因重新创建你用于onSaveInstanceState()后续数据提取的话onCreate().与使用类似的情况Fragment.newInstance(),唯一的区别是你不需要创建公共默认构造函数.
我理解错了吗?非常感谢你.
我对有关默认构造函数的错误消息感到困惑.
我有2个MainActivity和ResultDialog.MainActivity创建新对话框并将2strings传递给自定义构造函数的一些方法ResultDialog.
ResultDialog延伸DialogFragment.所以我定义了自己的构造函数,但是当出现错误时我刚刚创建了一个无参数的构造函数,但仍然不允许这样做.
我已经在SO上搜索了abit,但答案有点解释屏幕旋转可能会破坏并使用默认构造函数重新创建屏幕,但仍然无法回答我如何解决这个问题.
错误是避免片段中的非默认构造函数:使用默认构造函数加上Fragment #setArguments(Bundle)
有人请帮助我,我有点困惑.我ResultDialog班级的一部分:
public class ResultDialog extends DialogFragment {
private String message;//to hold the message to be displayed
private String title;//for alert dialog title
//constructor for the dialog passing along message to be displayed in the alert dialog
public ResultDialog(String message,String title){
this.message = message;
this.title = title;
}
public ResultDialog(){
//default constructor
}
Run Code Online (Sandbox Code Playgroud) 我正在Android使用 Kotlin开发应用程序。在我的应用程序中Tab,ViewPager我实现了两个选项卡。当我移动到另一个活动并压缩到选项卡视图活动时,应用程序停止并logcat显示在错误下方。
java.lang.RuntimeException:无法启动活动 ComponentInfo{com.crypto.wallet/com.crypto.wallet.activities.MainActivity}:android.support.v4.app.Fragment$InstantiationException:无法实例化片段 com.crypto.wallet .activities.ReceiveFragment:找不到片段构造函数
我的片段.kt
@SuppressLint("ValidFragment")
class ReceiveFragment(private val transactionList: List<TransactionEntity>, val appDatabase: AppDatabase, private val direction: TransactionAdapterDirection,
val networkDefinitionProvider: NetworkDefinitionProvider) : Fragment(){
private var linearLayoutManager: LinearLayoutManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val rootView = inflater.inflate(R.layout.receive_fragment, container, false)
val recyclerView = rootView.findViewById<RecyclerView>(R.id.transaction_recycler_in) as RecyclerView
linearLayoutManager = LinearLayoutManager(getActivity(), LinearLayout.VERTICAL, false)
recyclerView.layoutManager = linearLayoutManager
recyclerView.adapter = TransactionRecyclerAdapter(transactionList,appDatabase,direction,networkDefinitionProvider)
recyclerView.setHasFixedSize(true); …Run Code Online (Sandbox Code Playgroud) 我正在调用一个带有参数的对话框,如下所示:
MyDialog("title", "message").show(this@MyActivity.supportFragmentManager, null)
Run Code Online (Sandbox Code Playgroud)
这是我的对话类:
class MyDialog(private val theTitle: String, private val theMessage: String) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity.let {
val myBuilder = AlertDialog.Builder(it)
myBuilder
.setTitle(theTitle)
.setMessage(theMessage)
.setPositiveButton("OK") { _, _ -> }
myBuilder.create()
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是当设备的方向在旋转时发生变化时,应用程序将停止工作。如果没有传递参数,则不会发生这种情况。那么,如何传递参数以及这样做的最佳方法是什么?
我在片段中有以下构造函数:-
public PlaceDialogFragment(Place place, DisplayMetrics dm){
super();
this.mPlace = place;
this.mMetrics = dm;
}
Run Code Online (Sandbox Code Playgroud)
我也试过这个:-
public static final DialogFragment newInstance(Place place, DisplayMetrics dm)
{
DialogFragment fragment = new DialogFragment();
Bundle bundle = new Bundle(2);
bundle.putParcelable("Place", place);
bundle.putLong("Metrics", dm);
fragment.setArguments(bundle);
return fragment ;
}
Run Code Online (Sandbox Code Playgroud)
但是bundle.putLong("Metrics", dm) 网上有错误
这Place是一个实现 Parceable 接口的类
但我收到一条错误消息:-
Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead
Run Code Online (Sandbox Code Playgroud)
任何建议如何解决这个问题?