【问题标题】:Replace a fragment above another fragment when dialog is clicked (viewpager)单击对话框时替换另一个片段上方的片段(viewpager)
【发布时间】:2013-10-18 16:05:47
【问题描述】:

当在另一个片段中单击对话框时,我正在尝试打开一个片段。我正在使用带有 Tab 的 ActionBarSherlock。我的片段附加在视图寻呼机中。我几乎完成了这项工作。但我无法在视图寻呼机中替换新片段。我有一个错误。我读了线程here。解决办法不明确。

错误:

10-18 21:34:40.379:E/AndroidRuntime(19618):致命异常:主要 10-18 21:34:40.379: E/AndroidRuntime(19618): java.lang.IllegalArgumentException:未找到 id 0x7f040032 的视图 (com.example.actionbartestwithsherlock:id/pager) 用于片段 AllContactsFragment{41fd4ba0 #0 id=0x7f040032} 10-18 21:34:40.379: E/AndroidRuntime(19618):在 android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)

我与名为 FragmentTab1、FragmentTab2 和 FragmentTab3 的寻呼机有三个片段关联。

我的 MainActivityFragmentAdapter 如下所示:

  public class MainActivity extends SherlockFragmentActivity {

    ActionBar.Tab Tab1, Tab2, Tab3, Tab4;
    private Context context = this;
    // view pager
    // Declare Variables
    ActionBar actionBar;
    ViewPager mPager;
    Tab tab;
    FragmentAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // set application in portrait mode
        ActivityHelper.initialize(this);

        actionBar = getSupportActionBar();
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Locate ViewPager in activity_main.xml
        mPager = (ViewPager) findViewById(R.id.pager);
        // add an adapter to pager
        mPager.setAdapter(new FragmentAdapter(getSupportFragmentManager(),
                mPager, actionBar));

        addActionBarTabs();
    }

    private void addActionBarTabs() {

        String[] tabs = { "Tab 1", "Tab 2", "Tab 3" };
        for (String tabTitle : tabs) {
            ActionBar.Tab tab = actionBar.newTab().setText(tabTitle)
                    .setTabListener(tabListener);
            actionBar.addTab(tab);
        }
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    }

    private ActionBar.TabListener tabListener = new ActionBar.TabListener() {
        @Override
        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
            mPager.setCurrentItem(tab.getPosition());
        }

        @Override
        public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        }

        @Override
        public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
        }
    };

class FragmentAdapter extends FragmentPagerAdapter implements
            ViewPager.OnPageChangeListener {

        private ViewPager mViewPager;
        final int TOTAL_PAGES = 3;

        public FragmentAdapter(FragmentManager fm, ViewPager pager,
                ActionBar actionBar) {
            super(fm);
            this.mViewPager = pager;
            this.mViewPager.setOnPageChangeListener(this);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
            case 0:
                return FragmentTab1.newInstance();
            case 1:
                return FragmentTab2.newInstance();
            case 2:
                return FragmentTab3.newInstance();
            default:
                throw new IllegalArgumentException(
                        "The item position should be less or equal to:"
                                + TOTAL_PAGES);
            }
        }

        @Override
        public int getCount() {
            return TOTAL_PAGES;
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageSelected(int position) {
            actionBar.setSelectedNavigationItem(position);
        }
    }
}

现在,在我的第一个标签 FragmentTab1 中,我会在单击按钮时打开一个自定义对话框。我想在选择对话框选项时替换 FragmentTab1 中的新片段 AllContactsFragment

FragmentTab1 片段类:

public class FragmentTab1 extends SherlockFragment implements OnClickListener {

Button btnTest;
ViewPager pager;
LinearLayout layoutBlockNumbers;
LinearLayout layoutContact, layoutCallLog, layoutSMSLog, layoutManually;
Context context;
CustomizedDialog dialog;
private static final int CONTACT_PICKER_RESULT = 1001;
private static final String DEBUG_TAG = "Contact List";
private static final double RESULT_OK = -1;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragmenttab1, container,
            false);

    layoutBlockNumbers = (LinearLayout) rootView
            .findViewById(R.id.layoutAddBlockNumbers);
    layoutBlockNumbers.setOnClickListener(this);
    return rootView;

}

@Override
public void onClick(View v) {

    if (v == layoutCallLog) {

        dialog.dismiss();
        // want to replace new fragment at position 0 in pager
        // problem is here ??? how to open new fragmnet
        Fragment allContactsFragment = AllContactsFragment.newInstance();
        FragmentTransaction transaction = getChildFragmentManager()
                .beginTransaction();
        transaction.addToBackStack(null);
        transaction.replace(R.id.pager, allContactsFragment).commit();

    }

    if (v == layoutBlockNumbers) {
        // open a dialog
        showDialog();
    } else if (v == layoutContact) {
        openContactList();
        dialog.dismiss();
    } else if (v == layoutSMSLog) {
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    setUserVisibleHint(true);
}

// open a dialog
private void showDialog() {
    dialog = new CustomizedDialog(getActivity());
    dialog.setContentView(R.layout.dialog_add_number_type);
    dialog.setTitle("Add Black List Number");

    //initialize all linear layouts in dialog
    layoutCallLog = (LinearLayout) dialog.findViewById(R.id.layoutCallLog);
    layoutContact = (LinearLayout) dialog.findViewById(R.id.layoutContact);
    layoutSMSLog = (LinearLayout) dialog.findViewById(R.id.layoutSMSLog);
    layoutManually = (LinearLayout) dialog
            .findViewById(R.id.layoutManually);

    // add listener to several linear layout
    layoutContact.setOnClickListener(this);
    layoutCallLog.setOnClickListener(this);
    layoutSMSLog.setOnClickListener(this);
    layoutManually.setOnClickListener(this);

    dialog.show();
}

public static Fragment newInstance() {
    Fragment f = new FragmentTab1();
    return f;
} 
}

activity_main.xml 如下所示:

   <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" >

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    </android.support.v4.view.ViewPager>

</RelativeLayout>

谁能帮我解决这个问题?对不起,大量的代码。

【问题讨论】:

    标签: java android android-fragments actionbarsherlock android-viewpager


    【解决方案1】:

    我不确定您是否可以按照自己的方式做事。 ViewPager 的设置方式与普通容器/片段设置的方式不同。在ViewPager 中,您不是使用片段事务来添加片段,而是使用从后备列表加载片段实例的适配器。

    然后替换片段将如下工作:

    (1) 创建要添加的片段的实例 (2) 将该片段添加到支持您的PagerAdapter 的列表中 (3) 显示新片段 (4) 删除旧的

    在您当前的项目中实现此功能的问题在于您的适配器的设置。当前,您正在使用只能返回固定数量的片段的 switch 语句。你的适配器应该是这样设置的。

    class MyPageAdapter extends FragmentPagerAdapter{
        private List<Fragment> fragments  
        public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) { 
            super(fm); 
            this.fragments = fragments; 
        } 
    
        @Override  
        public Fragment getItem(int position) { 
            return this.fragments.get(position);   
        }   
    
        @Override   
        public int getCount() {     
            return this.fragments.size(); 
        } 
    }
    

    然后你可以在你的适配器类中添加一个方法来添加或删除新的片段。如果您知道要替换的片段的索引,那么这应该很容易。您所要做的就是创建联系人片段的新实例,将其添加到您的数组或列表中。 This Post 解释了 ViewPager 如何处理新内容的添加/删除以及如何确保显示您的新片段。

    【讨论】:

    • 我在哪里添加片段?在我的场景中添加如何?我很迷茫。将我视为初级程序员。
    • 我已经添加了旧片段列表并且效果很好。但我的问题是如何在对话框 onclick 事件中打开新片段?@Rarw
    • 您只需从 onclick 侦听器的回调中添加新片段
    【解决方案2】:

    在我阅读this 的帖子后,我解决了答案。

    我只是在我的 fragmenttab1.xml 的顶部布局中添加了一个 ID android:id="@+id/fragmentTabLayout1。然后调用 像往常一样的新片段:

        Fragment allContactsFragment = AllContactsFragment.newInstance();
            FragmentTransaction transaction = getChildFragmentManager()
                    .beginTransaction();
            transaction.addToBackStack(null);
            // use this id to replace new fragment
            transaction.replace(R.id.fragmentTabLayout1, allContactsFragment).commit();
    

    【讨论】:

      猜你喜欢
      • 2011-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多