加载带有片段的 SherlockFragmentActivity 时屏幕长时间空白

Posted

技术标签:

【中文标题】加载带有片段的 SherlockFragmentActivity 时屏幕长时间空白【英文标题】:Screen becomes blank for long time while loading SherlockFragmentActivity with fragments 【发布时间】:2013-12-01 05:03:27 【问题描述】:

我正在实现 jeremyfeinstein 滑动菜单库。为此,我有一个扩展 SherlockFragmentActivity 的活动。对于这个活动,我有两个片段,一个用于左侧菜单,另一个用于主屏幕。一切正常且顺利,但我仍然有一个问题,即当我的滑动菜单活动开始时,它会变为空白 8-10 秒。 8-10 秒后,我的主屏幕片段变得可见。 这是我的基类:

  public class SlidingFragmentActivity extends SherlockFragmentActivity implements SlidingActivityBase 

    private SlidingActivityHelper mHelper;

    /* (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        mHelper = new SlidingActivityHelper(this);
        mHelper.onCreate(savedInstanceState);
    

    /* (non-Javadoc)
     * @see android.app.Activity#onPostCreate(android.os.Bundle)
     */
    @Override
    public void onPostCreate(Bundle savedInstanceState) 
        super.onPostCreate(savedInstanceState);
        mHelper.onPostCreate(savedInstanceState);
    

    /* (non-Javadoc)
     * @see android.app.Activity#findViewById(int)
     */
    @Override
    public View findViewById(int id) 
        View v = super.findViewById(id);
        if (v != null)
            return v;
        return mHelper.findViewById(id);
    

    /* (non-Javadoc)
     * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) 
        super.onSaveInstanceState(outState);
        mHelper.onSaveInstanceState(outState);
    

    /* (non-Javadoc)
     * @see android.app.Activity#setContentView(int)
     */
    @Override
    public void setContentView(int id) 
        setContentView(getLayoutInflater().inflate(id, null));
    

    /* (non-Javadoc)
     * @see android.app.Activity#setContentView(android.view.View)
     */
    @Override
    public void setContentView(View v) 
        setContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    

    /* (non-Javadoc)
     * @see android.app.Activity#setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
     */
    @Override
    public void setContentView(View v, LayoutParams params) 
        super.setContentView(v, params);
        mHelper.registerAboveContentView(v, params);
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#setBehindContentView(int)
     */
    public void setBehindContentView(int id) 
        setBehindContentView(getLayoutInflater().inflate(id, null));
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#setBehindContentView(android.view.View)
     */
    public void setBehindContentView(View v) 
        setBehindContentView(v, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#setBehindContentView(android.view.View, android.view.ViewGroup.LayoutParams)
     */
    public void setBehindContentView(View v, LayoutParams params) 
        mHelper.setBehindContentView(v, params);
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#getSlidingMenu()
     */
    public SlidingMenu getSlidingMenu() 
        return mHelper.getSlidingMenu();
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#toggle()
     */
    public void toggle() 
        mHelper.toggle();
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#showAbove()
     */
    public void showContent() 
        mHelper.showContent();
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#showBehind()
     */
    public void showMenu() 
        mHelper.showMenu();
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#showSecondaryMenu()
     */
    public void showSecondaryMenu() 
        mHelper.showSecondaryMenu();
    

    /* (non-Javadoc)
     * @see com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivityBase#setSlidingActionBarEnabled(boolean)
     */
    public void setSlidingActionBarEnabled(boolean b) 
        mHelper.setSlidingActionBarEnabled(b);
    

    /* (non-Javadoc)
     * @see android.app.Activity#onKeyUp(int, android.view.KeyEvent)
     */
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) 
        boolean b = mHelper.onKeyUp(keyCode, event);
        if (b) return b;
        return super.onKeyUp(keyCode, event);
    


这是我加载片段的主要活动

public class SliderMenuMainActivity extends SlidingFragmentActivity

private Fragment mContent;
    ImageButton btnToggle,refresh;
    String ns = Context.NOTIFICATION_SERVICE;
    public static int msg_count = 0;
    
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        if(obj==null)
            obj=new Progress_Dialog(this);
        obj.setCancelable(false);
        obj.onPreExecute("MAIN Screen");
        if (savedInstanceState != null)
            mContent = getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
        prepareScreen();
    
private void prepareScreen()
    
        setContentView(R.layout.activity_slider_menu_main);
        
        ActionBar ab = getSherlock().getActionBar();
        LayoutInflater li = LayoutInflater.from(this);
        View customView = li.inflate(R.layout.custom_titlebar, null);
        customView.setLayoutParams(new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT ,ActionBar.LayoutParams.MATCH_PARENT));
        ab.setCustomView(customView);
        ab.setDisplayShowHomeEnabled(false);
        ab.setDisplayShowCustomEnabled(true);
if (findViewById(R.id.menu_frame) == null) 
        
            setBehindContentView(R.layout.menu_frame);
            getSlidingMenu().setSlidingEnabled(true);
            getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
            // show home as up so we can toggle
            //getSupportActionBar().setDisplayHomeAsUpEnabled(true);
         
        else 
        
            // add a dummy view
            View v = new View(this);
            setBehindContentView(v);
            getSlidingMenu().setSlidingEnabled(false);
            getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_NONE);
        

        
        if (mContent == null)
            mContent = new MainScreenFragment();    
        
            getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, mContent).commit();

        // set the Behind View Fragment
            getSupportFragmentManager().beginTransaction().replace(R.id.menu_frame, new MenuFragment()).commit();

        // customize the SlidingMenu
        SlidingMenu sm = getSlidingMenu();
        sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
        sm.setShadowWidthRes(R.dimen.shadow_width);
        sm.setShadowDrawable(R.drawable.shadow);
        sm.setBehindScrollScale(0.25f);
        sm.setFadeDegree(0.25f);
        setSlidingActionBarEnabled(false);
        
    
@Override
    public boolean onOptionsItemSelected(MenuItem item) 
        switch (item.getItemId()) 
        case android.R.id.home:
            toggle();
        
        return super.onOptionsItemSelected(item);
    
    @Override
    public void onSaveInstanceState(Bundle outState) 
        super.onSaveInstanceState(outState);
        getSupportFragmentManager().putFragment(outState, "mContent", mContent);
    
    public void switchContent(final Fragment fragment) 
        mContent = fragment;
        getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.content_frame, fragment)
        .commit();
        Handler h = new Handler();
        h.postDelayed(new Runnable() 
            public void run() 
                getSlidingMenu().showContent();
            
        , 50);
    
    
    @Override
    public void onResume()
    
        super.onResume();
        if(obj!=null)
            obj.onPostExecute();
    

所以请帮我解决这个问题,并告诉我解决这个问题的方法。提前致谢。

编辑 1

我已将所有代码放到 onResume() 中,但仍然存在同样的问题。现在大约需要 2 到 3 秒才能看到活动。为什么当我没有任何代码进入 onCreate() 时要花费这么多时间。我已经删除了所有的库,现在我只使用带有导航抽屉的支持库(4 和 7),结果相同。

【问题讨论】:

【参考方案1】:

问题:

显示空白屏幕,因为在执行 prepareScreen 之前未设置您的内容视图。

解决方案:

您需要将setContentView(R.layout.activity_slider_menu_main); 直接放在super.onCreate(savedInstanceState); 之后的onCreate 方法中。

【讨论】:

感谢您的快速回复。让我检查一下。 还是同样的问题... :( obj 是什么?如果您只是在加载视图时尝试显示进度对话框,则完全没有必要这样做。您可以毫无顾忌地删除它。 是的,我已经删除了它,但它不会改变结果。 我已经从 onCreate() 中删除了所有内容,并在 onResume() 中添加了代码,但它仍然需要大约 1 秒的时间才能变得可见【参考方案2】:

你在 onCreate() 中做了很多操作。您只需要设置主要布局和类似的东西。所有的操作都可以在 onResume() 中调用。

【讨论】:

是的,你是对的。我在 onCreate() 中做了很多操作,但这些是我项目的要求。如果我在 onResume() 中执行这些操作,那么每次都会调用它们,而不是像 onCreate() 一样单次调用它们。 那么你能做的就是把所有这些操作放在 AsyncTask 中并在 onCreate() 中调用它。在主线程中执行的操作是问题 是的,我已经尝试从 onCreate() 中删除所有操作,但同样需要同样的时间。您也可以通过运行上面的代码来检查它。

以上是关于加载带有片段的 SherlockFragmentActivity 时屏幕长时间空白的主要内容,如果未能解决你的问题,请参考以下文章

带有recyclerviews的碎片需要很长时间才能加载

带有片段的操作栏的行为? [关闭]

带有片段参数的 Grails render()

带有嵌套/子片段的 Android Backstack

在片段中重新加载android视图

带有活动和子片段的导航抽屉