精华内容
下载资源
问答
  • 序言FragmentAndroid v3.0版本开始引入的,随着界面布局的复杂化,处理起来也更加的复杂,...Fragment可以响应自己的输入事件,并拥有自己的生命周期,但它们的生命周期直接被其所属的Activity的生命周期控制。Fr...

    序言

    Fragment从Android v3.0版本开始引入的,随着界面布局的复杂化,处理起来也更加的复杂,引入Fragment可以把Activity拆分成多个部分。一个Activity可以同时组合多个Fragment,一个Fragment也可被多个Activity 复用。Fragment可以响应自己的输入事件,并拥有自己的生命周期,但它们的生命周期直接被其所属的Activity的生命周期控制。

    01d6949f2710

    Fragment生命周期流程图

    正文

    1. 生命周期简介

    Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。Fragment状态与Activity类似,也存在如下4种状态:

    运行:当前Fmgment位于前台,用户可见,可以获得焦点。

    暂停:其他Activity位于前台,该Fragment依然可见,只是不能获得焦点。

    停止:该Fragment不可见,失去焦点。

    销毁:该Fragment被完全删除,或该Fragment所在的Activity被结束。

    2. 生命周期状态

    Fragment的生命周期与Activity的生命周期十分相似,如下图所示:

    01d6949f2710

    Activity和Fragment生命周期对比流程图

    从上图可以看出,Activity中的生命周期方法,Fragment中基本都有,但是Fragment比Activity多几个方法。各生命周期方法的含义如下:

    onAttach() :

    当Fragment与Activity发生关联时调用。

    onCreate():

    创建Fragment时被回调。

    onCreateView():

    每次创建、绘制该Fragment的View组件时回调该方法,Fragment将会显示该方法返回的View 组件。

    onActivityCreated():

    当 Fragment 所在的Activity被启动完成后回调该方法。

    onStart():

    启动 Fragment 时被回调,此时Fragment可见。

    onResume():

    恢复 Fragment 时被回调,获取焦点时回调。

    onPause():

    暂停 Fragment 时被回调,失去焦点时回调。

    onStop():

    停止 Fragment 时被回调,Fragment不可见时回调。

    onDestroyView():

    销毁与Fragment有关的视图,但未与Activity解除绑定。

    onDestroy():

    销毁 Fragment 时被回调。

    onDetach():

    与onAttach相对应,当Fragment与Activity关联被取消时调用。

    3. 生命周期调用

    1)创建Fragment

    onAttach() —> onCreate() —> onCreateView() —> onActivityCreated() —> onStart() —> onResume()

    2)按下Home键回到桌面 / 锁屏

    onPause() —> onStop()

    3)从桌面回到Fragment / 解锁

    onStart() —> onResume()

    4)切换到其他Fragment

    onPause() —> onStop() —> onDestroyView()

    5)切换回本身的Fragment

    onCreateView() —> onActivityCreated() —> onStart() —> onResume()

    6) 按下Back键退出

    onPause() —> onStop() —> onDestroyView() —> onDestroy() —> onDetach()

    参考

    结语

    至此,Fragment的生命周期介绍完毕。Fragment具有与Activity很相似的生命周期,依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。

    展开全文
  • 我们大多数人都非常了解android活动生命周期,但还不了解片段生命周期。 片段生命周期如何与活动生命周期相互作用? 添加片段与替换片段有什么区别? 我们将在下面查看所有这些问题。 Android片段生命周期 ...

    无论您是准备面试还是要在应用程序中实现片段,您都应该了解片段的生命周期。

    我们大多数人都非常了解android活动生命周期,但还不了解片段生命周期。

    片段生命周期如何与活动生命周期相互作用? 添加片段与替换片段有什么区别?

    我们将在下面查看所有这些问题。

    Android片段生命周期

    android中的片段生命周期主要由以下8种方法组成:

    1. onCreate :用于初始化非图形组件。
    2. onCreateView :用于扩大片段的xml布局。
    3. onStart
    4. onResume
    5. 暂停
    6. onStop
    7. onDestroyView
    8. onDestroy

    这些构成了Android中的片段生命周期。 为了研究他们的通话顺序,我创建了一个示例项目。

    创建一个示例应用

    我们将以两种方式分析片段的生命周期。 首先通过动态添加片段,然后静态添加。

    在Android Studio中创建一个新项目。 这将是一个基础项目,我们将在所有生命周期方法中添加基本日志语句。

    在该项目中,添加一个名为LifecycleFragment的片段并覆盖生命周期方法。 如果尚未创建,请创建一个简单的布局xml。

     class LifecycleFragment : Fragment() { 
        var LOG_TAG = "Androidville" 
        companion object {
    
            @JvmStatic
    
            fun newInstance() = LifecycleFragment()
    
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
    
            super .onCreate(savedInstanceState)
    
            Log.d(LOG_TAG, "LifecycleFragment: onCreate() called" )
    
        }
    
        override fun onCreateView(
    
            inflater: LayoutInflater, container: ViewGroup?,
    
            savedInstanceState: Bundle?
    
        ): View? {
    
            Log.d(LOG_TAG, "LifecycleFragment: onCreateView() called" )
    
            return inflater.inflate(R.layout.fragment_lifecycle, container, false )
    
        }
    
        override fun onStart() {
    
            Log.d(LOG_TAG, "LifecycleFragment: onStart() called" )
    
            super .onStart()
    
        }
    
        override fun onResume() {
    
            Log.d(LOG_TAG, "LifecycleFragment: onResume() called" )
    
            super .onResume()
    
        }
    
        override fun onPause() {
    
            Log.d(LOG_TAG, "LifecycleFragment: onPause() called" )
    
            super .onPause()
    
        }
    
        override fun onStop() {
    
            Log.d(LOG_TAG, "LifecycleFragment: onStop() called" )
    
            super .onStop()
    
        }
    
        override fun onDestroy() {
    
            Log.d(LOG_TAG, "LifecycleFragment: onDestroy() called" )
    
            super .onDestroy()
    
        }
    
        override fun onDestroyView() {
    
            Log.d(LOG_TAG, "LifecycleFragment: onDestroyView() called" )
    
            super .onDestroyView()
    
        }
     }
    

    您会注意到我在所有这些方法中都添加了log语句,这将有助于我识别调用顺序。

    这是布局文件:

     <?xml version= "1.0" encoding= "utf-8" ?>
     <RelativeLayout xmlns:android= " http://schemas.android.com/apk/res/android "
    
        xmlns:tools= " http://schemas.android.com/tools "
    
        android:layout_width= "match_parent"
    
        android:layout_height= "match_parent"
    
        tools:context= ".LifecycleFragment" > 
        <TextView
    
            android:layout_width= "wrap_content"
    
            android:layout_height= "wrap_content"
    
            android:layout_centerInParent= "true"
    
            android:text= "Hello from Fragment!" />
     </RelativeLayout>
    

    动态添加片段

    以下是MainActivity.kt可以动态添加片段的代码:

     MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
    
        var TAG: String = "ANDROIDVILLE"
    
        var LOG_TAG = "Androidville" 
        override fun onCreate(savedInstanceState: Bundle?) {
    
            super .onCreate(savedInstanceState)
    
            setContentView(R.layout.activity_main)
    
            Log.d(LOG_TAG, "MainActivity: onCreate() called" )
    
            setupFragment()
    
        }
    
        private fun setupFragment() {
    
            supportFragmentManager.beginTransaction()
    
                    .add(R.id.contentFrame, LifecycleFragment.newInstance(), TAG)
    
                    .commit()
    
        }
    
        override fun onRestart() {
    
            Log.d(LOG_TAG, "MainActivity: onRestart() called" )
    
            super .onRestart()
    
        }
    
        override fun onStart() {
    
            Log.d(LOG_TAG, "MainActivity: onStart() called" )
    
            super .onStart()
    
        }
    
        override fun onResume() {
    
            Log.d(LOG_TAG, "MainActivity: onResume() called" )
    
            super .onResume()
    
        }
    
        override fun onPause() {
    
            Log.d(LOG_TAG, "MainActivity: onPause() called" )
    
            super .onPause()
    
        }
    
        override fun onStop() {
    
            Log.d(LOG_TAG, "MainActivity: onStop() called" )
    
            super .onStop()
    
        }
    
        override fun onDestroy() {
    
            Log.d(LOG_TAG, "MainActivity: onDestroy() called" )
    
            super .onDestroy()
    
        }
     }
    

    这是布局activity_main.xml

     <?xml version= "1.0" encoding= "utf-8" ?>
     <RelativeLayout 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:layout_width= "match_parent"
    
        android:layout_height= "match_parent"
    
        tools:context= ".MainActivity" > 
        <FrameLayout
    
            android:id= "@+id/contentFrame"
    
            android:layout_width= "match_parent"
    
            android:layout_height= "wrap_content" />
     </RelativeLayout>
    

    静态添加片段

    要静态添加片段,我们只需在activity_main.xml文件中添加<fragment>元素,并将其名称设置为kotlin类。布局:

     <?xml version= "1.0" encoding= "utf-8" ?>
     <RelativeLayout xmlns:android= " http://schemas.android.com/apk/res/android "
    
        xmlns:tools= " http://schemas.android.com/tools "
    
        android:layout_width= "match_parent"
    
        android:layout_height= "match_parent"
    
        tools:context= ".MainActivity" > 
        <fragment
    
            android:id= "@+id/lifecycle_fragment"
    
            android:name= "com.example.androidfragmentlifecycleexample.LifecycleFragment"
    
            android:layout_width= "match_parent"
    
            android:layout_height= "match_parent" />
     </RelativeLayout>
    

    MainActivity.kt文件:

     MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
    
        var TAG: String = "ANDROIDVILLE"
    
        var LOG_TAG = "Androidville" 
        override fun onCreate(savedInstanceState: Bundle?) {
    
            super .onCreate(savedInstanceState)
    
            setContentView(R.layout.activity_main)
    
            Log.d(LOG_TAG, "MainActivity: onCreate() called" )
    
        }
    
        override fun onRestart() {
    
            Log.d(LOG_TAG, "MainActivity: onRestart() called" )
    
            super .onRestart()
    
        }
    
        override fun onStart() {
    
            Log.d(LOG_TAG, "MainActivity: onStart() called" )
    
            super .onStart()
    
        }
    
        override fun onResume() {
    
            Log.d(LOG_TAG, "MainActivity: onResume() called" )
    
            super .onResume()
    
        }
    
        override fun onPause() {
    
            Log.d(LOG_TAG, "MainActivity: onPause() called" )
    
            super .onPause()
    
        }
    
        override fun onStop() {
    
            Log.d(LOG_TAG, "MainActivity: onStop() called" )
    
            super .onStop()
    
        }
    
        override fun onDestroy() {
    
            Log.d(LOG_TAG, "MainActivity: onDestroy() called" )
    
            super .onDestroy()
    
        }
     }
    

    Android Fragment Lifecycle回调序列

    最后,让我们看看运行应用程序时片段中的生命周期回调序列是什么。

    动态添加

    当我们动态添加片段时,将发生以下回调序列。

    您可以在此处看到该活动已创建。 首先调用Activity的onCreate,onStart

    然后调用片段的onCreate,onCreateView和onStart。 最后,分别调用Activity和Fragment的onResume。

    退出应用程序时:

    在这里,活动先被破坏,然后是片段。 因此,活动的onPause,onStop和onDestroy分别在片段之前被首先调用。

    静态添加

    当我看到这个生命周期回调序列时,我也感到惊讶。 将片段静态添加到活动中后,便会急切创建片段。

    退出应用程序时:

    与静态加法相同。 活动首先被破坏,然后被破坏。

    添加或替换片段

    顾名思义,当您添加一个片段时,它会被添加到容器中已有片段的顶部。 但是,如果您调用replace,则容器中的片段将被新片段替换。

    这意味着,如果您尝试在活动中按TAG检索片段,则替换片段而不是添加片段就不会找到它。

    翻译自: https://www.javacodegeeks.com/2020/09/android-fragment-lifecycle-explained.html

    展开全文
  • Fragment生命周期是什么?为什么ViewPager中Fragment来回滑动但是onResume没有调用?Activity与Fragment的声明周期有何不同?Fragment生命周期套用一张google的官方图片:onAttach(): 完成Fragment和Activity的...

    Fragment的生命周期是什么?为什么ViewPager中Fragment来回滑动但是onResume没有调用?Activity与Fragment的声明周期有何不同?

    Fragment的生命周期

    套用一张google的官方图片:

    f100848ea2eed17b1fa92c1f240f07c3.png

    onAttach(): 完成Fragment和Activity的绑定,参数中的Activity即为要绑定的Activity,可以进行赋值等操作。

    onCreate() : 完成Fragment的初始化

    onCreateView() : 加载View布局,绑定布局文件

    onActivityCreated() : 与Fragment绑定的Activity已经执行完成了onCreate,可以与Activity进行交互操作。

    onStart() : Fragment变为可见状态

    onResume() : Fragment变为可交互状态

    onPause(): Fragment变为不可交互状态(不代表不可见)

    onSaveInstanceState():保存当前Fragment的状态。记录一些数据,比如EditText键入的文本,即使Fragment被回收又重新创建,一样能恢复EditText之前键入的文本。

    onStop(): Fragment变为不可见状态

    onDestroyView() : 销毁Fragment的有关视图,但并未和Activity解绑,可以通过onCreateView()重新创建视图。Fragment销毁时或者ViewPager+Fragment情况下会调用

    onDestroy() : 销毁Fragment时调用。

    onDetach() : 解除和Activity的绑定。Fragmen销毁最后一步

    Activity与Fragment生命周期的区别

    20171118194453260.png

    可以十分明了的看到,当Activity处于不同生命周期时Fragment生命周期的流程。需要关注一下两者生命周期顺序问题,其中onCreate、onStart、onResume都是Activity先调用之后才是Fragment,onPause、onStop、onDestroy(在Fragment中是onDetach),是先Fragment调用之后才是Activity。其他的就不展开说了,图十分明了。

    Fragment相关操作对生命周期的影响

    添加Fragment可以分为静态添加和动态添加两大类。静态添加是在XML中直接添加Fragment,简单方便,缺点是添加之后不能在删除。动态添加是在代码中FragmentManger使用一系列FragmentTransaction事务操作动态控制,灵活多变。一般都是使用动态添加,下面就讲讲动态添加有关的生命周期。

    add:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume

    remove:onPause->onStop->onDestroyView->onDestroy->onDetach

    show:onHiddenChanged(boolean hidden) hidden为false

    hide:onHiddenChanged(boolean hidden) hidden为true

    replace:旧Fragment的remove生命周期->新Fragment的add生命周期

    replace+addToBackStack:onPause->onStop->onDestroyView->新Fragment的add生命周期

    之后点击back:新Fragment的remove,然后旧的Fragment从BackStack(Fragment栈)中恢复:onCreateView->onViewCreated->onActivityCreated->onStart->onResume 就是第一张图的线

    detach:onPause->onStop->onDestroyView 可以看到只是视图被移除,Fragment关联状态还是不变,还是处于FragmentManger的管理下

    FragmentTransaction.attach(Fragment var1):onStart->onResume->onCreateView

    注意:Fragment的show和hide仅仅是将Fragment视图设置为是否可见,不会调用任何生命周期。该Fragment的生命周期还是会随着Activity的生命周期变化而变化,例如FragmentA hide、FragmentB show,点击Home A和B都会onPause->onStop

    应用被系统回收对生命周期的影响

    应用被回收一般都是后台应用,所以生命周期是从onDestroyView开始

    单独一个Fragment

    onDestroyView->onDestroy->onDetach->add生命周期

    Fragment A hide,Fragment B show

    A.onDestroyView->A.onDestroy->A.onDetach->B.onDestroyView->B.onDestroy->B.onDetach->A.onAttach->A.onCreate->B.onAttach->B.onCreate->A.onCreateView->A.onActivityCreated->B.onCreateView->B.onActivityCreated->A.onStart->B.onStart->A.onResume->B.onResume

    为了防止在系统回收应用情况下,再次进不出错,强烈建议大家

    1. 使用setArguments(Bundle bundle)方法传递参数。对于常规变量想必大家都已经十分熟练了,就不细说了。这里主要强调View变量和接口变量,View变量可以通过传入View的id,之后再通过id获取view的方法来实现。接口可以通过Activity实现,Fragment强转Activity实现。

    2. addFragment之前先通过findFragmentById判断是否添加过避免重复添加,如使用FragmentAdapter可以在onSaveInstanceState存储相应Fragment.getTag

    ViewPager对Fragment生命周期的影响

    ViewPager+Fragment已经是比较常见的组合,一般搭配ViewPager的FragmentPagerAdapter或FragmentStatePagerAdapter使用。不过ViewPager为了防止滑动出现卡顿,有一个缓存机制,默认情况下ViewPager会创建并缓存当前页面左右两边的页面(如Fragment)。此时左右两个Fragment都会执行从onAttach->….->onResume的生命周期,明明Fragment没有显示却已经到onResume了,然后滑动fragment时又不会调用onResume,onPause,在某些情况下会出现问题。比如数据的加载时机、判断Fragment是否可见等。

    那么应该如何处理呢?可以使用一下方法来判断Fragment是否可见

    @Override

    public void onHiddenChanged(boolean hidden) {

    super.onHiddenChanged(hidden);

    if (!hidden) {

    reportPageShow();

    }

    }

    展开全文
  • 我有一个FragmentActivity,它使用TabManager显示片段,如下所示:public class WorkOrderFormTabFragmentActivity extends FragmentActivity {TabHost mTabHost;TabManager mTabManager;@Overrideprotected void onC....

    我遇到一个问题,我找不到任何解释.

    我有一个FragmentActivity,它使用TabManager显示片段,如下所示:

    public class WorkOrderFormTabFragmentActivity extends FragmentActivity {

    TabHost mTabHost;

    TabManager mTabManager;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.work_order_form_tab_new);

    mTabHost = (TabHost)findViewById(android.R.id.tabhost);

    mTabHost.setup();

    mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent);

    mTabManager.addTab(mTabHost.newTabSpec("form").setIndicator("Form"),

    WorkOrderFormFragment.class, null);

    mTabManager.addTab(mTabHost.newTabSpec("pictures").setIndicator("Pictures"),

    PictureListFragment.class, null);

    if (savedInstanceState != null) {

    mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));

    }

    }

    @Override

    protected void onSaveInstanceState(Bundle outState) {

    super.onSaveInstanceState(outState);

    outState.putString("tab", mTabHost.getCurrentTabTag());

    }

    public static class TabManager implements TabHost.OnTabChangeListener {

    private final FragmentActivity mActivity;

    private final TabHost mTabHost;

    private final int mContainerId;

    private final HashMap mTabs = new HashMap();

    TabInfo mLastTab;

    static final class TabInfo {

    private final String tag;

    private final Class> clss;

    private final Bundle args;

    private Fragment fragment;

    TabInfo(String _tag, Class> _class, Bundle _args) {

    tag = _tag;

    clss = _class;

    args = _args;

    }

    }

    static class DummyTabFactory implements TabHost.TabContentFactory {

    private final Context mContext;

    public DummyTabFactory(Context context) {

    mContext = context;

    }

    @Override

    public View createTabContent(String tag) {

    View v = new View(mContext);

    v.setMinimumWidth(0);

    v.setMinimumHeight(0);

    return v;

    }

    }

    public TabManager(FragmentActivity activity, TabHost tabHost, int containerId) {

    mActivity = activity;

    mTabHost = tabHost;

    mContainerId = containerId;

    mTabHost.setOnTabChangedListener(this);

    }

    public void addTab(TabHost.TabSpec tabSpec, Class> clss, Bundle args) {

    tabSpec.setContent(new DummyTabFactory(mActivity));

    String tag = tabSpec.getTag();

    TabInfo info = new TabInfo(tag, clss, args);

    info.fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);

    if (info.fragment != null && !info.fragment.isDetached()) {

    FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();

    ft.detach(info.fragment);

    ft.commit();

    }

    mTabs.put(tag, info);

    mTabHost.addTab(tabSpec);

    }

    @Override

    public void onTabChanged(String tabId) {

    TabInfo newTab = mTabs.get(tabId);

    if (mLastTab != newTab) {

    FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();

    if (mLastTab != null) {

    if (mLastTab.fragment != null) {

    //ft.detach(mLastTab.fragment);

    ft.hide(mLastTab.fragment);

    }

    }

    if (newTab != null) {

    if (newTab.fragment == null) {

    newTab.fragment = Fragment.instantiate(mActivity,

    newTab.clss.getName(), newTab.args);

    ft.add(mContainerId, newTab.fragment, newTab.tag);

    } else {

    //ft.attach(newTab.fragment);

    ft.show(newTab.fragment);

    }

    }

    mLastTab = newTab;

    ft.commit();

    mActivity.getSupportFragmentManager().executePendingTransactions();

    }

    }

    }

    在FragmentActivity的第二个选项卡中,用户可以管理图片列表,并使用相机添加更多图片.

    片段代码:

    public class PictureListFragment extends Fragment {

    static final int TAKE_PICTURE_ACTIVITY = 1;

    static final int EDIT_PICTURE_ACTIVITY = 2;

    FormPictureListAdapter lvAdapter;

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup viewgrp,

    Bundle savedInstanceState) {

    // Inflate the layout for this fragment

    View cont = inflater.inflate(R.layout.form_picture_list, viewgrp, false);

    LinearLayout container = (LinearLayout)cont.findViewById(R.id.formPictureListLayout);

    try{

    final Context context = getActivity();

    ListView ls2 = new ListView(context);

    // clear previous results in the LV

    ls2.setAdapter(null);

    // populate

    ArrayList pictures = new ArrayList();

    //pictures.add(0, new MFPicture());

    pictures.addAll(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures());

    lvAdapter = new FormPictureListAdapter(context, pictures);

    ls2.setAdapter(lvAdapter);

    LinearLayout.LayoutParams Params = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, 0, 1f);

    ls2.setLayoutParams(Params);

    ls2.setOnItemClickListener(new OnItemClickListener() {

    public void onItemClick(AdapterView> parent, View view,

    int position, long id) {

    final MFPicture picture = ((MFPictureView)view).getPicture();

    final int idx = position;

    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {

    @Override

    public void onClick(DialogInterface dialog, int which) {

    switch (which){

    case DialogInterface.BUTTON_POSITIVE:

    //Edit picture

    EditPictureActivity.setPicture(picture);

    Intent configurationOpen = new Intent(getActivity(), EditPictureActivity.class);

    startActivityForResult(configurationOpen, EDIT_PICTURE_ACTIVITY);

    break;

    case DialogInterface.BUTTON_NEGATIVE:

    //Delete picture

    ((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures().remove(idx);

    MFUtils.deleteFile(picture.getPath());

    lvAdapter.updatePictureList(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures());

    lvAdapter.notifyDataSetChanged();

    break;

    }

    }

    };

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    builder.setMessage(getResources().getString(R.string.wo_bem_regie_list_el_action)).setPositiveButton(getResources().getString(R.string.wo_bem_regie_list_el_edit), dialogClickListener)

    .setNegativeButton(getResources().getString(R.string.wo_bem_regie_list_el_delete), dialogClickListener).show();

    }

    });

    container.addView(ls2);

    LayoutInflater layoutInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View view=layoutInflater.inflate(R.layout.add_btn_bottom,container);

    view.setBackgroundResource(R.drawable.list_selector_even);

    TextView text = (TextView)view.findViewById(R.id.title);

    text.setText(getResources().getString(R.string.wo_picturelist_add));

    view.setOnClickListener(new OnClickListener() {

    @Override

    public void onClick(View v){

    v.setBackgroundResource(R.drawable.list_selector_even);

    String pictureFile = ((MFApplication)getActivity().getApplication()).getNextPictureFile();

    String picPath = MFUtils.MF_STORAGE_PATH+"/"+pictureFile;

    Log.e("FormPictureListActivity", "PicturePath : "+picPath);

    //setBackgroundResource(android.R.drawable.list_selector_background);

    try {

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(picPath)));

    startActivityForResult(intent, TAKE_PICTURE_ACTIVITY);

    } catch (ActivityNotFoundException e) {

    Log.e("FormPictureListActivity", "Call failed", e);

    }

    }

    });

    }

    catch(Exception e){

    e.printStackTrace();

    Log.e("FormPictureListActivity", "Error:", e);

    }

    return cont;

    }

    @Override

    public void onActivityResult(int requestCode, int resultCode, Intent data) {

    //super.onActivityResult(requestCode, resultCode, data);

    String pictureFile = ((MFApplication)getActivity().getApplication()).getPictureFile();

    Log.d("FormPictureListActivity", "ActivityResult:"+resultCode);

    Log.d("FormPictureListActivity", "ActivityResult-picFile:"+pictureFile);

    if (requestCode == TAKE_PICTURE_ACTIVITY){

    if(resultCode == getActivity().RESULT_OK){

    Log.d("FormPictureListActivity", "ActivityResult:OK");

    MFPicture picture = new MFPicture(MFPicture.TYPE_PICTURE, MFUtils.MF_STORAGE_PATH+"/"+pictureFile);

    ((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures().add(picture);

    lvAdapter.updatePictureList(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures());

    lvAdapter.notifyDataSetChanged();

    EditPictureActivity.setPicture(picture);

    Intent configurationOpen = new Intent(getActivity(), EditPictureActivity.class);

    startActivityForResult(configurationOpen, EDIT_PICTURE_ACTIVITY);

    }

    }

    else if (requestCode == EDIT_PICTURE_ACTIVITY){

    EditPictureActivity.getPicture().setComment(EditPictureActivity.getPicture().getCommentUIValue());

    lvAdapter.updatePictureList(((MFApplication)getActivity().getApplication()).getCurrentForm().getPictures());

    lvAdapter.notifyDataSetChanged();

    }

    }

    }

    一切都可以在我的测试设备(Nexus 5,Galaxy Nexus,Galaxy Mini 2)上正常运行,但是我会不时收到其他我无法访问的设备(主要是运行Android 4.0.4的设备)的错误消息:

    java.lang.RuntimeException: Unable to resume activity

    {com.mf.mobile.android/com.mf.mobile.android.WorkOrderFormTabFragmentActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, data=null} to activity {com.mf.mobile.android/com.mf.mobile.android.WorkOrderFormTabFragmentActivity}: java.lang.NullPointerException

    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2616)

    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2644)

    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2130)

    at android.app.ActivityThread.access$600(ActivityThread.java:135)

    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1248)

    at android.os.Handler.dispatchMessage(Handler.java:99)

    at android.os.Looper.loop(Looper.java:137)

    at android.app.ActivityThread.main(ActivityThread.java:4645)

    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:809)

    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)

    at dalvik.system.NativeStart.main(Native Method)

    Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=131073, result=-1, data=null} to activity {com.mf.mobile.android/com.mf.mobile.android.WorkOrderFormTabFragmentActivity}: java.lang.NullPointerException

    at android.app.ActivityThread.deliverResults(ActivityThread.java:3156)

    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2599)

    ... 12 more

    Caused by: java.lang.NullPointerException

    at com.timewise.mobile.android.fragments.PictureListFragment.onActivityResult(PictureListFragment.java:138)

    at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:166)

    at android.app.Activity.dispatchActivityResult(Activity.java:4662)

    at android.app.ActivityThread.deliverResults(ActivityThread.java:3152)

    ... 13 more

    NPE出现在以下代码行中:

    ????lvAdapter.updatePictureList(((MframeApplication)getActivity()getApplication())getCurrentForm()getPictures());

    这意味着此时lvAdapter变量为null.但是这个变量应该已经在Fragment的onCreateView中设置了.这使我认为,在某些时候,可能已经在不调用onCreateView的情况下重新创建了Fragment.

    我找不到有关此问题的任何解释.你能帮我这个忙吗?

    非常感谢

    展开全文
  • Fragment生命周期详解

    2021-06-06 13:38:12
    序言FragmentAndroid v3.0版本开始引入的,随着界面布局的复杂化,处理起来也更加的复杂,...Fragment可以响应自己的输入事件,并拥有自己的生命周期,但它们的生命周期直接被其所属的Activity的生命周期控制。 F...
  • 一、Fragment生命周期1.onAttach->onCreate.....->onDestroy->onDettach这条生命周期是一个完整的生命周期,onAttach表示从Actitivity附着,onDettach表示从Activity剥离,一般来说,调用add方法后悔有这...
  • Glide中一个重要特性是Request可以随Activity或Fragment的onStart而resume,onStop而pause,onDestroy而clear,从而节约流量和内存,并且...而不是Application,不然没办法进行生命周期管理而现在,我自己就有这种...
  • -----------------------------------------------------------------------fragment生命周期---------------------------------------------------------------------- 代码默认定位到朋友界面,但是测试代码在...
  • 一、Fragment的事务再讲Fragment生命周期之前,一定要讲一下FragmentTransaction也就是fragment的事务,这对我们理解生命周期有很重要的作用。那么什么是事务?根据用户的交互情况,对fragment...
  • 目录概述Fragment的使用Fragment生命周期总览与...Android从3.0开始引入了Fragment,其优点包括可适配、可重用、多样化等,本文将重点放在对Fragment生命周期的学习上。 Fragment的使用 首先记录一下Fragment的使
  • 1、activity嵌套frament ,生命周期方法执行顺序activity和fragment生命周期方法.png2、横竖屏切换activity生命周期方法调用情况(android10)(1)不设置Activity的android:configChanges打开activity>>>>&...
  • 网上有很多Fragment生命周期的帖子,但是看了一下,没有找到自己想了解的东西,于是决定自己动手体验一下这个生命周期。主要想了解以下几个问题:Activity中的Fragment的生命周期ViewPager中Frament的生命周期...
  • 我使用add()和replace()语句在片段之间切换并跟踪其生命周期.Fragment1添加Fragment2添加Fragment3添加Fragment4添加Fragment5替换Fragment6log-cat显示他们的生命周期(我有一些printf点在onCreate,onCreateView,o.....
  • 死磕 Fragment生命周期本文原创,转载请注明出处。欢迎关注我的 简书 ,关注我的专题 Android Class 我会长期坚持为大家收录简书上高质量的 Android 相关博文。本篇文章已授权微信公众号 guolin_blog (郭霖)独家...
  • 前情提要(Previously)本系列将使用 Android Studio 将《第一行代码》(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Android Studio 作为...系列目录在此:Fragment生命周期先来看一下 Fr...
  • 【Android开发】之Fragment生命周期androidfragment上一篇博客我们讲到了,Fragment的基本使用,相信大家都已经了解怎么去使用了。如果还有不懂得同学可以去看一下,传送门。现在我们来讲解一下Fragment的生命周期...
  • onCreate:Activity正在创建,生命周期的第一个方法,需要setContentView加载layout。这里不建议耗时操作,只做layout和控件初始化。此方法传递一个 Bundle 对象,可以获取上一个Activity 的状态。onStart:Activity...
  • 首先,我们创建一个Activity和一个Fragment,并在Fragment的各个生命周期打好日志,并把Fragments丢进Viewpager,这里我们往Viewpager里丢了3个Fragment,够用了。同时设置Viewpager.adapter = FragmentPagerAdapter...
  • 'androidx.navigation:navigation-fragment:2.1.0' 'androidx.navigation:navigation-ui:2.1.0' 'androidx.navigation:navigation-fragment-ktx:2.1.0' 'androidx.navigation:navigation-ui-ktx:2.1.0' 复制代码 ...
  • 1.mNavController.navigate(R.id.xxxx)执行结果 //启动Fragment A BaseFragment--onAttach CallPatientAFragment{249d69f4} BaseFragment--onCreate CallPatientAFragment{249d69f4} BaseFragment--onCreateView ...
  • Fragment 可以翻译成片段,说白了就是占用的一块空间,这块空间可以被替换成其他的资料空间,常见的案例如 新闻,咨询……点击新闻在没有在活动间跳转的情况下使用的就是片段替换 1、Activity活动和Fragment片段...
  • Fragment:(Fragment就相当于一个有生命周期的View,它的生命周期被所在的Activity的生命周期管理)生命周期回调说明:onAttach(Activity)当Fragment与Activity发生关联时调用。onCreateView(LayoutInflater, ViewGroup...
  • Fragment必须是依存于Activity而存在的,因此Activity的生命周期会直接影响到Fragment生命周期。官网这张图很好的说明了俩者的关系:可以看到Fragment比Activity多了几个额外的生命周期回调函数:onAttach...
  • Activity和Fragment生命周期有哪些? activity生命周期为: onCreate()初始化加载布局→onStart()正在启动,不在前台在后台→onResume()获取焦点→onPause()停止,界面可见→onStop()停止,界面不可见→onDestroy()...
  • 简介 是从Android3.0开始新增的概念, 意为碎片, 而且是因为专门为平板设计的 用来组建Activity界面的局部模块, ...同时fragment生命周期受activity的影响 本质上会产生一个FrameLayout,它加载的布局
  • 最近在做一个项目中用到了viewpager+fragment实现的功能,但是出现了一些问题,尤其是fragment生命周期的问题,有人会说了这生命周期有什么难的,不就是按顺序回调么,显示回调哪些,隐藏回调哪些…… 这大家都知道...
  • 本文将带你了解Android应用开发之FragmentFragment相互切换之间的生命周期方法,希望本文对大家学Android有所帮助。Fragment 1 切换到 Fragment 2时生命周期变化1、通过 add hide show 方式来切换 ...
  • 使用FragmentTabHost作为底部,FrameLayout占位,搭建主页框架:android:id="@+id/home_content_fl"android:layout_width="0dp"android:layout_height="0dp"android:background="@color/color_working_area_bg"app:...
  • 要创建一个fragment,必须创建一个 Fragment 的子类 (或者继承自一个已存在的它的子类)。Fragment类的代码看起来很...事实上,如果你准备将一个现成的Android应用转换到使用fragment,可能只需简单的将代码从你的act...
  • 如上是一张Fragment生命周期图,其实不是很完整在 onCreateView---->onStart之间应该是 onCreateView->onViewCreated->onActivityCreated->onViewStateRestored->onStart 按照我们Fragment的优化方案,应该分2类优化...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,267
精华内容 13,306
关键字:

安卓fragment生命周期