从文档开始:
public void setRetainInstance(boolean retain)
控制是否在活动重新创建(例如从配置更改)中保留片段实例.这只能用于不在后栈中的片段.如果设置,则在重新创建活动时,片段生命周期会略有不同:
- onDestroy()不会被调用(但是onDetach()仍然会被调用,因为片段正在与其当前活动分离.
- 因为片段没有被重新创建,所以不会调用onCreate(Bundle).
- onAttach(Activity)和onActivityCreated(Bundle)仍将被调用.
我有一些问题:
片段是否也保留其视图,还是会在配置更改时重新创建?"保留"究竟是什么意思?
当用户离开活动时,片段是否会被销毁?
为什么它不适用于后端堆栈上的碎片?
哪个是使用此方法有意义的用例?
我得到了一个应用程序TransactionTooLargeException的错误跟踪.不可重复,从未有过.在文档中说
Binder事务失败,因为它太大了.
在远程过程调用期间,调用的参数和返回值将作为存储在Binder事务缓冲区中的Parcel对象传输.如果参数或返回值太大而不适合事务缓冲区,则调用将失败并抛出TransactionTooLargeException.
...
当远程过程调用抛出TransactionTooLargeException时,有两种可能的结果.客户端无法将其请求发送到服务(很可能,如果参数太大而无法放入事务缓冲区中),或者服务无法将其响应发送回客户端(最有可能的话,如果返回值为太大而不适合事务缓冲区).
...
所以,好吧,我正在传递或接收超出某个未知限制的参数.但是哪里?
堆栈跟踪不会显示我的文件中的任何内容:
java.lang.RuntimeException: Adding window failed
at android.view.ViewRootImpl.setView(ViewRootImpl.java:548)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
... 16 more
android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at …Run Code Online (Sandbox Code Playgroud) 我正在使用Fragments其中一个创建一个应用程序,我创建了一个非默认构造函数并得到了这个警告:
Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead
Run Code Online (Sandbox Code Playgroud)
谁能告诉我为什么这不是一个好主意?
你能否建议我如何做到这一点:
public static class MenuFragment extends ListFragment {
public ListView listView1;
Categories category;
//this is my "non-default" constructor
public MenuFragment(Categories category){
this.category = category;
}....
Run Code Online (Sandbox Code Playgroud)
不使用非默认构造函数?
我写了一个在两个片段之间切换的虚拟活动.当您从FragmentA转到FragmentB时,FragmentA会被添加到后台堆栈中.但是,当我返回FragmentA(通过按回)时,会创建一个全新的FragmentA,并且它所处的状态将丢失.我感觉我跟这个问题一样,但我已经包含了一个完整的代码示例来帮助解决问题:
public class FooActivity extends Activity {
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, new FragmentA());
transaction.commit();
}
public void nextFragment() {
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, new FragmentB());
transaction.addToBackStack(null);
transaction.commit();
}
public static class FragmentA extends Fragment {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View main = inflater.inflate(R.layout.main, container, false);
main.findViewById(R.id.next_fragment_button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
((FooActivity) getActivity()).nextFragment();
}
});
return main;
} …Run Code Online (Sandbox Code Playgroud) 我有2个片段:(1)Frag1(2)Frag2.
bundl = new Bundle();
bundl.putStringArrayList("elist", eList);
Frag2 dv = new Frag2();
dv.setArguments(bundl);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.the_fragg,dv);
ft.show(getFragmentManager().findFragmentById(R.id.the_fragg));
ft.addToBackStack(null);
ft.commit();
Run Code Online (Sandbox Code Playgroud)
如何在Frag2中获取此数据?
我正在使用Parcelable类.如何java.util.Date在此类中读取和写入对象?
我知道"newInstance"-Pattern(实例化新Android片段的最佳实践).但是,如果另一个片段更改数据,如何更新片段的这些参数?
我知道片段/活动之间的回调方法,但这些回调不会更新参数?!
例如:在创建片段时,我使用bundle将URI传递给它.然后另一个片段通过第一个片段上的changeUri(Uri uri)方法回调来更改此URI.如果然后片段被重新创建(例如由于屏幕旋转),它将使用参数包中的第一个URI而不是后来更新的uri,对吗?
解决这个问题的最佳做法是什么?我是否必须手动将其存储在savedInstanceState中,并在使用时决定是使用instanceState还是arguments-bundle?
我正在寻找一种处理我的片段参数的标准方法,所以我想我会采用这种方法(伪代码):
private Uri arg1;
public static Fragment newInstance(Uri arg1) {
create bundle
create fragment instance
set bundle to fragment
return fragment
}
private void onCreate(Bundle savedInstance) {
if(savedInstance != null) {
arg1 = savedInstance.uri
}
}
private Uri getUri() {
if(arg1 == null) {
arg1 = getArguments.uri
}
if(arg1 == null) {
arg1 = defaultValue
}
}
Run Code Online (Sandbox Code Playgroud)
所以我有一个简单统一的方式来访问我的论点.每次我需要这个论点时,不必使用if-else-hassle.
你怎么看待这件事?
我想用导航抽屉制作一个简单的应用程序,它可以打开其他视图(新闻,信息,图库,联系人等).所以我打开了最新的Android Studio,制作了一个与API8> API19兼容的新项目,以获得最大的覆盖面.
我选择了预设的导航抽屉并点击完成.我已经想出要更改导航抽屉中项目的名称,但是如何让这些项目重定向到新视图?
我已经尝试将setOnItemClickListener实现到MainActivity中,如导航抽屉网站在http://developer.android.com上所述.但我似乎无法弄清楚这一切是如何联系在一起的,它不会起作用.
tl; dr:我需要帮助让导航抽屉中的项目启动一个新的视图/片段,并可能解释它是如何工作的.
这是应用程序项目(Android Studio)https://www.dropbox.com/s/qfz9oul62dzt3rr/NTI_SHOWCASE.zip
MainActivity.java
package com.christianarne.ntishowcase;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.DrawerLayout;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
private static final int SETTINGS_RESULT = 1;
/**
* Fragment …Run Code Online (Sandbox Code Playgroud) 我是代码审查其他人的ViewPager实现.他有一个属于每个视图的片段类数组.在getItem(int i)中,他会编写MyFragment.newInstance(),我认为没有问题.但是,查看ViewPager的google doc,他们在他们的示例中使用Fragment.instantiate.除了设置类信息的方式之外,使用实例化而不是调用newInstance(arg)或空构造函数有什么设计优势吗?
我正在尝试创建一个包含5个片段的ViewPager.5个片段"容器",因此每个片段包含2个片段.4个第一个片段具有相同的布局并属于同一个类.第五个来自另一个班级,那个没有问题.
问题是当活动启动时,只有1个片段似乎正在工作(viewPager中位置0的片段).我试图在我的PagerAdapter中的第0位返回新的Fragment(),但是当我这样做时,它是第二个正在工作的片段.(通过工作我的意思是在左边显示列表,我仍然没有处理右边的细节片段)
这是一些代码
CustomPagerAdapter.java
public class CustomPagerAdapter extends FragmentPagerAdapter{
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
public CustomPagerAdapter(FragmentManager fm, Context context) {
super(fm);
}
@Override
public Fragment getItem(int pos) {
if(pos == 4)
return new OtherContainerFragment();
else
return new ContainerFragment(pos);
}
@Override
public int getCount() {
return 5;
}
Run Code Online (Sandbox Code Playgroud)
ContainerFragment.java
public class ContainerFragment extends Fragment {
private int CONTAINER_TYPE;
public ContainerFragment(){
}
public ContainerFragment(int type){
CONTAINER_TYPE = type;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater …Run Code Online (Sandbox Code Playgroud) android android-layout android-fragments android-viewpager android-nested-fragment