Android пользовательский макет вкладки фон выбранной вкладки
Я настраиваю небольшое приложение, которое требует макета вкладки. Я реализовал все с фрагментами, и все работает очень хорошо, единственное, что я не могу понять, это фон выбранной вкладки: вот что я сделал:
Я начал с примеров "вкладок и пейджеров" ActionBarSherlock. Я поместил вкладки в горизонтальный вид прокрутки и создал в папке для рисования следующий селектор под названием tab_bg_selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Active tab -->
<item android:state_selected="true" android:state_focused="false"
android:state_pressed="false" android:drawable="@drawable/tab_selected" />
<!-- Inactive tab -->
<item android:state_selected="false" android:state_focused="false"
android:state_pressed="false" android:drawable="@drawable/tab_deselected" />
<!-- Pressed tab -->
<item android:state_pressed="true" android:drawable="@android:color/transparent" />
<!-- Selected tab (using d-pad) -->
<item android:state_focused="true" android:state_selected="true"
android:state_pressed="false" android:drawable="@android:color/transparent" />
</selector>
и вкладки добавляются таким образом
mTabsAdapter.addTab(getTabSpec(STEPS.STEP1_MATERIAL, "firstTab"), FirstTab.class, null);
где mTabsAdapter - класс, расширяющий FragmentPagerAdapter (созданный разработчиком примера, ниже для всех приведен код для полноты), а getTabSpec - это
public TabSpec getTabSpec(String tag, String title) {
View tabview;
TabSpec ts;
tabview = createTabView(mTabHost.getContext(), title);
ts = this.mTabHost.newTabSpec(tag).setIndicator(tabview).setContent(new TabContentFactory() {
public View createTabContent(String tag) {
return new TextView(getApplicationContext());
}
});
return ts;
}
и createTabView это
private View createTabView(final Context context, final String text) {
View view = LayoutInflater.from(context).inflate(R.layout.tabs_bg, null);
TextView tv = (TextView) view.findViewById(R.id.tabsText);
tv.setText(text);
return view;
}
R.layout.tabs_bg is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabsLayout" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="@drawable/tab_bg_selector"
android:padding="10dip" android:gravity="center" android:orientation="vertical">
<TextView android:id="@+id/tabsText" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Title"
android:textSize="15dip" android:textColor="@drawable/tab_text_selector" />
</LinearLayout>
tab_text_selector это
это класс, экземпляр которого mTabAdapter
/**
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. 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 pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter 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 paged in the ViewPager whenever the selected
* tab changes.
*/
public class TabsAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private TabInfo mLastTab = null;
final class TabInfo {
public final String tag;
public final Class<?> clss;
public final Bundle args;
public Fragment fragment;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
class TabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public TabFactory(Context context) {
mContext = context;
}
@Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new TabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
info.fragment = getSupportFragmentManager().findFragmentByTag(tag);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
try {
TabInfo newTab = (TabInfo) mTabs.get(position);// this.mapTabInfo.get(tag);
if (mLastTab != newTab) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(TabFragment.this, newTab.clss.getName(), newTab.args);
ft.add(android.R.id.tabcontent, newTab.fragment, newTab.tag);
} else {
ft.attach(newTab.fragment);
}
}
mLastTab = newTab;
ft.commit();
getSupportFragmentManager().executePendingTransactions();
}
} catch (Exception e) {
LogHelper.WriteLogError("error in onTabChanged function", e);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
// TabWidget widget = mTabHost.getTabWidget();
// int oldFocusability = widget.getDescendantFocusability();
// widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
// mTabHost.getTabWidget().focusCurrentTab(position);
// widget.setDescendantFocusability(oldFocusability);
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
Хорошо, после всего этого кода вот проблема:
Селектор для невыбранных вкладок работает нормально (за исключением textColor, который является белым, а не черным), но когда я выбираю вкладку, вкладка становится полностью черной, я снова нажимаю на вкладку, и все отображается правильно. вот изображение, чтобы лучше объяснить проблему
Я действительно не могу понять, в чем проблема, я надеюсь, что кто-то может здороваться со мной
Спасибо
РЕДАКТИРОВАТЬ: я обнаружил проблему: во время инициализации макета вкладки я поместил все вкладки, чтобы быть фокусируемыми в сенсорном режиме, потому что, когда по коду мне нужно показать вкладку, которая не видна (вкладок может быть много), используя
mTabHost.getTabWidget().focusCurrentTab(position)
которые не работают, если я не устанавливаю вкладки для фокусировки в сенсорном режиме.
Я могу решить это?
Спасибо