Intereting Posts
Как обновить наблюдаемые в RxJava? Facebook login Не удается передать разрешение на публикацию или управление (электронное письмо) на запрос авторизации на чтение Стратегия фрагментации кучи Android? SecurityException при попытке добавить учетную запись Получить имя текущего текущего метода Мой оператор «return» не работает, даже если нет других ветвей кода Нет ActionBar в PreferenceActivity после обновления до поддержки библиотеки v21 Как изменить пользовательский шрифт элемента меню Android? Как понять структуру каталогов корневого дерева android? Использование RxJava внутри адаптера RecyclerView Текст уведомления NotificationCompat, который не отображается при обновлении уведомления Внедрить расширяемый ListView с помощью пользовательского адаптера Как правильно маскировать Bitmap с помощью LinearGradient shader? Android EditText Горизонтальная полоса прокрутки не перемещается Нарисуйте географически точную дугу на карте для Android

Android; Фрагменты перекрываются при переключении вкладок

Прежде всего, спасибо всем вам за это великое сообщество.

Я пытаюсь выполнить пример кода демонстрации поддержки для реализации интерфейса с вкладками-фрагментами.

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

В настоящее время у меня есть два вопроса (но я уверен, что они связаны …)

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

2) Третий фрагмент тайны создается где-то и перекрывает другие фрагменты


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

Когда выбрано tab1, фрагмент 1 и неизвестный фрагмент перекрываются.

Когда tab2 выбран, фрагмент 1 и фрагмент 2 перекрываются.


Ссылки на скриншоты (недостаточно репутации для загрузки фотографий …)

(Перекрытие tab1) http://s8.postimg.org/kv81yz745/tab1_overlapping.png

(Tab2 overlapping) http://s8.postimg.org/3tf7wvs91/tab2_overlapping.png


Здесь я разделил текст в каждом фрагменте для целей демонстрации / ясности.

Ссылки на эти скриншоты приведены ниже в моем комментарии / ответе. (Недостаточно репутации для загрузки более двух ссылок …)

Макет действий (fragment_tabs.xml)

<TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TabWidget android:id="@android:id/tabs" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0"/> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="0"/> <FrameLayout android:id="@+id/realtabcontent" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> </TabHost> 

Исходный код

 public class TabbedInfoHome extends SherlockFragmentActivity { TabHost mTabHost; TabManager mTabManager; static String tag1name = "simple1"; static String tag2name = "simple2"; static String tab1string = "You are looking at fragment 1"; static String tab2string = "You are looking at fragment 2"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_tabs); if (savedInstanceState == null) { // Do first time initialization -- add initial fragment. Fragment frag1 = CountingFragment.newInstance(tab1string); Fragment frag2 = CountingFragment.newInstance(tab2string); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(R.id.realtabcontent, frag1, tag1name); ft.add(R.id.realtabcontent, frag2, tag2name); ft.commit(); } else { mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); } mTabHost = (TabHost)findViewById(android.R.id.tabhost); mTabHost.setup(); mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent); mTabManager.addTab(mTabHost.newTabSpec(tag1name) .setIndicator(tag1name), TabbedInfoHome.CountingFragment.class, null); mTabManager.addTab(mTabHost.newTabSpec(tag2name) .setIndicator(tag2name), TabbedInfoHome.CountingFragment.class, null); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("tab", mTabHost.getCurrentTabTag()); } public static class CountingFragment extends SherlockFragment { String displayString; String FRAGMENT_TAG = this.getClass().getSimpleName(); /** * Create a new instance of CountingFragment, providing "num" * as an argument. */ static CountingFragment newInstance(String toDisplay) { CountingFragment f = new CountingFragment(); Bundle args = new Bundle(); args.putString("string", toDisplay); f.setArguments(args); return f; } /* When creating, retrieve this instance's number from its arguments. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); displayString = getArguments() != null ? getArguments().getString("string") : "no string was passed in!"; } /* The Fragment's UI is just a simple text view showing its * instance number. */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.hello_world, container, false); View tv = v.findViewById(R.id.text); boolean separateStrings = false; /* the overlapping is hard to decipher, so * lets illustrate how both fragments are appearing */ if(separateStrings) { String temp; /* b/c I only created TWO instances of the CountingFragments object, * there should only be TWO "displayStrings" to consider... */ if( (displayString.compareTo(tab1string) == 0) ) { /* user clicked tab 1 */ temp = "\n\n\n\n" + displayString; } else if( (displayString.compareTo(tab2string) == 0) ) { /* user clicked tab2 */ temp = "\n\n\n\n\n\n\n" + displayString; } else { /* unknown CountingFragment instance */ temp = "What am I doing here..??? "; } ((TextView)tv).setText(temp); } else { /* normal case of the fragment being shown; (but they overlap!) */ ((TextView)tv).setText(displayString); } return v; } } /** * This is a helper class that implements a generic mechanism for * associating fragments with the tabs in a tab host. It relies on a * trick. Normally a tab host has a simple API for supplying a View or * Intent that each tab will show. This is not sufficient for switching * between fragments. So instead we make the content part of the tab host * 0dp high (it is not shown) and the TabManager supplies its own dummy * view to show as the tab content. It listens to changes in tabs, and takes * care of switch to the correct fragment shown in a separate content area * whenever the selected tab changes. */ public static class TabManager implements TabHost.OnTabChangeListener { private final FragmentActivity mActivity; private final TabHost mTabHost; private final int mContainerId; private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>(); 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); // Check to see if we already have a fragment for this tab, probably // from a previously saved state. If so, deactivate it, because our // initial state is that a tab isn't shown. info.fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag); if (info.fragment != null ) { // && !info.fragment.isDetached()) { Log.d("addingTab", "we already have a fragment for this tab. tabInfo.fragment.id: " + info.fragment.getId()); FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); ft.detach(info.fragment); ft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } // associate the tabSpec tag with a particular TabInfo object 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); } } 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); } } mLastTab = newTab; ft.commit(); mActivity.getSupportFragmentManager().executePendingTransactions(); } } } 

Solutions Collecting From Web of "Android; Фрагменты перекрываются при переключении вкладок"

После нескольких дней экспериментов я получил это, чтобы работать правильно.

В методе onCreate моего класса TabbedInfoHome при создании новых экземпляров фрагментов в первый раз ( savedInstanceState == null ) я принудительно this.getSupportFragmentManager().executePendingTransactions() ожидающие транзакции в FragmentTransaction с помощью this.getSupportFragmentManager().executePendingTransactions()

Это объяснение немного отличается от документации, найденной по адресу: http://developer.android.com/reference/android/app/FragmentManager.html#executePendingTransactions ()

После того, как FragmentTransaction выполняется с помощью FragmentTransaction.commit() , его планируется выполнить асинхронно > в основном потоке процесса. Если вы хотите немедленно выполнить любые такие ожидающие операции операции, вы можете вызвать эту функцию.

Один из нерешенных вопросов, который у меня остается, заключается в том, как отсутствие немедленного выполнения незавершенных транзакций проявляется в поведении, рассматриваемом в исходном вопросе.

Другими словами … как делает this.getSupportFragmentManager().executePendingTransactions() объясняет перекрывающиеся фрагменты?


Отредактированный код приведен ниже; Добавление одной строки

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_tabs); if (savedInstanceState == null) { // Do first time initialization -- add initial fragment. Fragment frag1 = CountingFragment.newInstance(tab1string); Fragment frag2 = CountingFragment.newInstance(tab2string); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(R.id.realtabcontent, frag1, tag1name); ft.add(R.id.realtabcontent, frag2, tag2name); ft.commit(); this.getSupportFragmentManager().executePendingTransactions(); // <----- This is the key } else { mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); } mTabHost = (TabHost)findViewById(android.R.id.tabhost); mTabHost.setup(); mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent); mTabManager.addTab(mTabHost.newTabSpec(tag1name) .setIndicator(tag1name), TabbedInfoHome.CountingFragment.class, null); mTabManager.addTab(mTabHost.newTabSpec(tag2name) .setIndicator(tag2name), TabbedInfoHome.CountingFragment.class, null); } 

Я также получаю эту проблему на Nexus 5.

Я думаю, что у нас есть другое решение лучше, чем удалять решение, используя этот способ.

Во all your xml files необходимо определить цвет фона для него, это решит проблему:

Добавьте этот android:background="@android:color/black" в тег View, который вы определили.

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

В моем случае я не использую SherlockActionBar, но решение должно работать на вас.

В той части, где вы проверяете, есть ли фрагмент, завышенный для вкладки, я использую:

  // in order to avoid fragment Fragment prevFragment; FragmentManager fm = mActivity.getFragmentManager(); prevFragment = fm.findFragmentByTag(mTag); if (prevFragment != null) { mFragment = prevFragment; } // \previous Fragment management 

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

Надеюсь, это сработает для вас!

Дано много решений, но я не смог решить проблему из-за глупой ошибки. Проблема заключалась в том, что в новом SDK по умолчанию активность расширена до «ActionbarActivity», в которой создается фрагмент, но они перекрываются. Чтобы решить эту проблему, расширяет вашу деятельность до «FragmentActivity»