Как я могу показать новый фрагмент на одной вкладке? - PullRequest
8 голосов
/ 01 августа 2011

Я создаю три вкладки, которые содержат один фрагмент, теперь я хочу заменить фрагмент первой вкладки новым фрагментом в той же вкладке. Как я могу сделать это, оставив вкладку такой же?

Мой код -

Tab_Widget.java

    public class Tab_Widget extends TabActivity {

            TabHost tabHost; 

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.tab_host);

            tabHost = getTabHost();

            tabHost.addTab(tabHost.newTabSpec("Tab1")
                .setIndicator("Tab1")
                .setContent(new Intent().setClass(this, main_activity.class)));

            tabHost.addTab(tabHost.newTabSpec("Tab2")
                .setIndicator("Tab2")
                .setContent(new Intent().setClass(this, second_activity.class)));

            tabHost.addTab(tabHost.newTabSpec("Tab3")
                    .setIndicator("Tab3")
                    .setContent(new Intent().setClass(this, third_activity.class)));

            tabHost.setCurrentTab(0);
        }
     }

main_activity.java

public class main_activity extends FragmentActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainfragment);
    }
}

main_fragment.java

public class main_fragment extends Fragment
{
    LinearLayout mLayout;
    Button mButton;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        mLayout = (LinearLayout) inflater.inflate(R.layout.main_view, null);
        mButton = (Button) mLayout.findViewById(R.id.btn);
        mButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                Fragment mFragment = new third_fragment_view();
                FragmentTransaction ft = getFragmentManager().beginTransaction();
//              ft.replace(R.id.Maincontainer, mFragment);
                ft.replace(R.id.main_fragment, mFragment);
                ft.addToBackStack(null);
                ft.commit();
            }
        });
        return mLayout;
    }
}

Мой XML

mainfragment.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/Maincontainer"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
  android:name="com.fragment.main_fragment"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:id="@+id/main_fragment">
</fragment>
</LinearLayout>

Таким образом, этот Фрагмент вызывается без сомнения, но он перекрывает предыдущий Фрагмент.

Ответы [ 3 ]

7 голосов
/ 03 августа 2011

У вас есть такая структура:

TabActivity
 -> Tab1 = FragmentActivity = MainFragment
 -> Tab2          
 -> Tab3          

Внутри MainFragment вы пытаетесь заменить содержимое его контейнера (самого себя).

Было бы лучше, если бы MainFragment вызывал настраиваемую TabActivity, которая, в свою очередь, вызывала замену в своем контейнере, или как-то так (что может привести к нарушению той же проблемы, поскольку он в основном выполняет тот же код из того же места , но это должно дать вам базовое представление о том, что я предлагаю):

    Fragment newFragment = new FragmentToChangeTo();
    CustomTabActivity tabActivity = (CustomTabActivity) getActivity();
    tabActivity.changeFragment(newFragment);

Если это не сработает, попробуйте сделать аналогичную вещь, но вместо того, чтобы вызывать действие, напрямую передавайте ему команды через Intents & Actions (или Bundles), содержащие информацию о том, что изменить в какой контейнер.

Я бы предпочел сказать / почему / фрагменты плохо работают с фрагментами во фрагменте и связанными с ними сложностями: отметьте здесь , чтобы понять, почему я предлагаю вырезать фрагменты из-под контроля фрагментов.

5 голосов
/ 02 августа 2011

ОК, несколько вещей:

  1. Вам не нужно и заменять, и удалять. Эффективная замена просто удаляет первый фрагмент и добавляет второй на его место.

  2. Я подозреваю, что ваши аргументы неверны для команды замены. Это правильная форма:

    replace (int containerViewId, Fragment fragment)
    

    Похоже, вы передаете идентификатор самого фрагмента, а не идентификатор контейнера. Команда replace берет идентификатор представления контейнера и удаляет все фрагменты в этом контейнере перед добавлением нового. Так что, если это был ваш макет:

    <LinearLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
        <fragment class="com.example.stackoverflow.YourFragmentName"
        android:id="@+id/main_fragment"
        android:layout_weight="1"
        android:layout_width="0px"
        android:layout_height="match_parent" />
    
    </LinearLayout>
    

    Вы бы использовали:

    replace(R.id.container, mFragment);
    

    а не

    replace(R.id.main_fragment, mFragment);
    
  3. Поскольку вы пытаетесь findFragmentById(R.id.main_fragment), я подозреваю, что вы добавили этот фрагмент в файл XML-макета. Если у вас есть фрагмент, добавленный непосредственно в XML, вы не можете удалить его программно во время выполнения. Чтобы удалить или заменить фрагменты, вы должны добавить их с помощью FragmentTransaction во время выполнения.

EDIT:

Числа 2 и 3 из моего первоначального ответа все еще применяются Вам нужно использовать идентификатор содержащей ViewGroup для добавления и замены. В данном случае это ваш LinearLayout, R.id.Maincontainer, а не R.id.main_fragment.

Кроме того, как я уже говорил, вы не можете удалять фрагменты, которые вы добавили непосредственно в XML. Ваш main_fragment добавлен в XML и поэтому не может быть удален во время выполнения.

Попробуйте это для своего mainfragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/Maincontainer"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <Button
    android:id="@+id/btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Switch Fragments">

</LinearLayout>

И это для вашего класса main_fragment:

public class main_activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainfragment);

        //Notice that I am adding this 1st fragment in the Activity and not the XML
        main_fragment mainFragment = new main_fragment();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(R.id.Maincontainer, mainFragment);
        ft.commit();

        mButton = (Button) findViewById(R.id.btn);
        mButton.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {

                Fragment mFragment = new third_fragment_view();
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                //Replacing using the id of the container and not the fragment itself
                ft.replace(R.id.Maincontainer, mFragment);
                ft.addToBackStack(null);
                ft.commit();
            }
        });
    }
}
0 голосов
/ 16 января 2012

@ theisenp Я создаю вид вкладки в том, что при нажатии кнопки она должна перейти на другой экран, когда я пытаюсь реализовать ее с помощью приведенного выше кода, она меняется на другой экран, но кнопка все еще видна на следующем экране ия хочу, чтобы следующий экран покрывал весь экран

public class Tab1Fragment extends Fragment  {
LinearLayout mLayout;
/** (non-Javadoc)
 * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
 */
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    if (container == null) {


        return null;
    }

    LinearLayout theLayout = (LinearLayout)inflater.inflate(R.layout.tab_frag1_layout, container, false);

            // Register for the Button.OnClick event

            Button b = (Button)theLayout.findViewById(R.id.button1);

            b.setOnClickListener(new View.OnClickListener() {



                @Override

                public void onClick(View v) {

                     Fragment mFragment = new third_fragment_view();
                     android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction();

                     ft.replace(R.id.container, mFragment);
                     ft.addToBackStack(null);
                     ft.commit();   


                }

            });

    return theLayout;

}
}

activity is displaying partially

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...