Подтвердить что ты не робот

Android: фрагменты, перекрывающие проблему

Я сталкиваюсь с проблемой перекрытия фрагментов, когда я переключаюсь между вкладками и прикрепляю фрагменты к виду вкладки ниже мой код, пожалуйста, помогите

public class FragmentManage extends Fragment implements ActionBar.TabListener {

    private Fragment mFragment;

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

        View v = inflater.inflate(R.layout.fragment_manage, container, false);

        OnClickListener clickListener = new OnClickListener() { 
            public void onClick(View v) {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                switch(v.getId()) {
                    case R.id.imageBtnCategory:
                        if (mFragment == null){
                            mFragment = new FragmentCategory();
                        }
                        ft.replace(android.R.id.content, mFragment);
                        break;
                    case R.id.imageBtnManageKey:
                        if (mFragment == null){
                            mFragment = new FragmentKeys();
                        }
                        ft.replace(android.R.id.content, mFragment);
                        break;
                    case R.id.imageBtnChangePswd:
                        if (mFragment == null){
                            mFragment = new FragmentChangePwd();
                        }
                        ft.replace(android.R.id.content, mFragment);
                        break;
                }
                ft.commit();
             }
        };

        ImageButton imageBtnCategory = (ImageButton) v.findViewById(R.id.imageBtnCategory);
        ImageButton imageBtnManageKey = (ImageButton) v.findViewById(R.id.imageBtnManageKey);
        ImageButton imageBtnChangePswd = (ImageButton) v.findViewById(R.id.imageBtnChangePswd);

        imageBtnCategory.setOnClickListener(clickListener);
        imageBtnManageKey.setOnClickListener(clickListener);
        imageBtnChangePswd.setOnClickListener(clickListener);

        return v;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        mFragment = new FragmentManage();
        ft.add(android.R.id.content, mFragment);
        ft.attach(mFragment);
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(mFragment);
    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {

    }
}
4b9b3361

Ответ 1

Просто установите цвет фона для вашего <fragment/> в файле XML.

Решает проблему.

Ответ 2

Возможно, мне очень поздно ответить на этот вопрос.

Примечание:

Этот ответ не может быть связан с вышеуказанным вопросом, но надеюсь, что это поможет некоторым.

Иногда проблема перекрытия фрагментов возникает, когда мы пытаемся использовать разные типы фрагментов (т.е. используя фрагмент поддержки в нескольких фрагментах и ​​нормальных фрагментах в другом фрагменте)

Недавно я столкнулся с такой же проблемой в навигационном ящике. По ошибке я использовал " import android.support.v4.app.Fragment;" в одном фрагменте и использовал " import android.app.Fragment;" в нескольких других фрагмент.

Надеюсь, это поможет кому-то.

Ответ 3

менеджер фрагментов поддерживает стек всех предыдущих фрагментов, которые заменяются, иногда фрагменты заднего стека перекрываются с замененным фрагментом, для меня

  fragmentManager.popBackStack(); 

работает, мы можем сделать это в цикле, чтобы вскрыть все фрагменты в стеке, надеюсь, что это поможет, спасибо. Счастливое кодирование:)

Ответ 4

Ну Настройка цвета фона фрагмента не является решением, потому что фрагмент будет по-прежнему находиться в стеке активности, который может потреблять память.

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

private void changeFragment(Fragment fr){
    FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
    fl.removeAllViews();
    FragmentTransaction transaction1 = getSupportFragmentManager().beginTransaction();
    transaction1.add(R.id.mainframe, fr);
    transaction1.commit();
}

Ответ 5

Вот как я его исправил..

Установка фона приведет к удалению эффекта перекрытия с экрана, только если макет соответствует заполнению экрана

Новые фрагменты, замененные на нажатия кнопок, не заменялись в tab_selected или действии изменения вкладок

следующий код исправил это для меня

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    // This is required since button click replaces fragment whose link is lost hence overlapping isuee was occuring
    ft.replace(android.R.id.content, mFragment); 
    // On Tab Change remove old fragment views
    ft.remove(mFragment);
}

Ответ 6

Другая проблема может быть связана с использованием android.R.id.content в качестве контейнера. Я только что создал FrameLayout и использую id оттуда.

Ответ 7

Я также столкнулся с проблемой перекрытия фрагментов. Вот как я ее решил -

1) Нам нужно добавить первый фрагмент с помощью addToBackStack, чтобы он сохранялся в стеке -

FirstFragment firstFragment = new FirstFragment();
getFragmentManager().beginTransaction().add(R.id.fragment_container, firstFragment).addToBackStack("first frag").commit();

2) При добавлении второго фрагмента замените первый фрагмент, а затем добавьте его. Поскольку первый фрагмент уже добавлен в стек, он будет присутствовать при нажатии на второй фрагмент -

SecondFragment secondFragment= new SecondFragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack("second frag").commit();

3) Вот как можно работать с обратным прессом, ниже код должен присутствовать в родительской активности -

 public void onBackPressed(){
    if(getFragmentManager().getBackStackEntryCount() <= 1){
       super.onBackPressed();
    } else {
       getFragmentManager().popBackStack();
    }
 }

Ответ 8

private void changeFragment(Fragment fr){
FrameLayout fl = (FrameLayout) findViewById(R.id.mainframe);
fl.removeAllViews();
FragmentTransaction transaction1 =getSupportFragmentManager().beginTransaction();
transaction1.add(R.id.mainframe, fr);
transaction1.commit();}

Ответ 9

когда у вас есть фрагмент перекрытия, возможно, ваш фон вашего фрагмента прозрачен, вам нужно поставить андроид: background = "@color/white" 'внутри ваших фрагментов propeties

<FrameLayout 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:background="@color/white"

и белый цвет вам нужно вставить в color.xml #FFFFFF в папке для отдыха.

Ответ 10

У меня иногда та же проблема, но моя проблема не связана с разными менеджерами фрагментов (getSupportFragmentManager(), getFragmentManager()). Я думаю, что есть еще одна проблема. В моем случае, когда я открываю ящик навигации, я всегда удаляю старые фрагменты в каждом пункте меню, например:

Fragment calendarFragment = context.getSupportFragmentManager().findFragmentByTag(FragmentTag.CALENDAR.name());
if (calendarFragment != null)
{
    context.getSupportFragmentManager().beginTransaction().remove(calendarFragment).commit();
}

Невозможно попасть в подменю без навигационного ящика, поэтому фрагменты в основном всегда удаляются. В некоторых случаях, после того, как я удаляю и добавляю фрагмент снова внутри Activity, он внезапно перекрывается с другим (предыдущим) фрагментом?! Но почему менеджер фрагментов неожиданно обнаруживает предыдущие фрагменты? Это может означать, что диспетчер фрагментов неисправен, и он не удаляет старые фрагменты или что-то другое не работает.
Моя мысль заключается в том, что это как-то по вине Android Studio или любого другого инструмента разработки adb, который используется им. Почему я так думаю, потому что Android Studio иногда, похоже, потеряет экземпляр запущенного приложения. Вероятно, эта проблема каким-то образом связана с одной и той же проблемой: Android Studio не развертывает изменения в приложении. Я еще не понял, когда это произойдет. Я знаю, что это не может быть проблемой программирования, потому что она не воспроизводится после того, как я перезапустил приложение Android Studio. Я думаю, что есть какие-то фоновые процессы, зависающие, что вызывает несколько экземпляров "Действия", "Фрагменты", "Менеджеры фрагментов" и т.д. Кроме того, это не просто эта ошибка. В прошлом я видел много странных поведений, которые похожи на это. (Например, поведение внезапно исчезло, когда приложение не было запущено с помощью IDE).

Ответ 11

Все это связано с разработкой методов замены и addToBackStack.

Метод замены фактически сделает две вещи. Скройте существующий фрагмент (пусть говорят A) и добавьте новый (пусть говорят B) в контейнер.

Добавление этой транзакции в задний стек будет делать обратное. Удалите B и добавьте A.

Итак, решение вашей проблемы - это  1. используйте метод addToBackStack.
 2. убедитесь, что обратная замена фрагментов - правильный порядок

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

Ответ 12

Сделать цвет фона белым для меня тоже. Я думаю, что это проблема с ошибкой и проблемой в менеджере фрагментов Android. Я правильно выполнял свою замену и popBackStack().

Ответ 13

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

Ответ 14

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

backstack выглядит следующим образом и думает, что вы на фраг 4, 1-> 2, 2-> 3, 3-> 4, но вы на самом деле на фраг 6 по какой-то причине, так что popbackstack идет

удалить (4) добавить (3) <- теперь у вас есть 3 (новые) и 6 (оставленные позади), смешанные вместе

Чтобы лучше контролировать навигацию, я отслеживаю текущие/предыдущие фрагменты и заменяю их следующим образом. Это позволяет моему приложению контролировать навигацию по фрагментам.

if ( !(currentFragment instanceof Settings)) {
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container, settings);
        fragmentTransaction.addToBackStack(null);
        previousFrag = currentFragment;
        currentFragment = settings;
        fragmentTransaction.commit();
    }

Во-вторых, я считаю, что метод fragranager.replace() является лучшей альтернативой. Не уверен, что это доступно для OP в то время.

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

fragmentTransaction.addToBackStack (нуль);

Однако, если это так, вы должны проверить, если приложение загружается впервые. Если это не так, и вы исключаете эту строку, то ваше приложение будет сталкиваться с этими проблемами при каждой навигации по этому фрагменту. Я предпочитаю оставить его на месте и сделать следующее.

Не уверен, что это считается хорошим решением, но оно работает очень хорошо.

1- получить количество обратных стеков 2- удалить все существующие фрагменты 3- отслеживать ваши фрагментированные объекты 4-, если это последний фрагмент в стеке, который пользователь желает выйти, и поскольку мы добавили основное действие в задний стек, мы нужно удвоить поп

@Override
public void onBackPressed() {

int num = getFragmentManager().getBackStackEntryCount();


        fl.removeAllViews();
        super.onBackPressed();

        if  (currentFragment != previousFrag) {
            currentFragment = previousFrag;
        }else{
            currentFragment = null;
        }

        if (num == 1){
           super.onBackPressed();
        }

Ответ 15

Я нашел простое и чистое решение. Для меня проблема заключалась в выполнении транзакции фрагмента в каждом вызове onCreate() моей Activity. Теперь я выполняю транзакцию, только если saveInstanceState == null

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (savedInstanceState == null) {
        // replace fragment 
        }
    }

Ответ 16

Вы проверили свой XML и посмотрите, является ли основной макет Frame Layout? Если нет, используйте вместо этого Frame Layout. Это решит проблему с перекрытием. Это единственный способ исправить. Я попробовал "принятый" ответ, когда искал решение этой проблемы, и оно не сработало.