1 /* 2 ** 3 ** Copyright 2013, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 package com.android.packageinstaller; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.graphics.Rect; 22 import android.support.v4.view.PagerAdapter; 23 import android.support.v4.view.ViewPager; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.TabHost; 27 import android.widget.TabWidget; 28 29 import java.util.ArrayList; 30 31 /** 32 * This is a helper class that implements the management of tabs and all 33 * details of connecting a ViewPager with associated TabHost. It relies on a 34 * trick. Normally a tab host has a simple API for supplying a View or 35 * Intent that each tab will show. This is not sufficient for switching 36 * between pages. So instead we make the content part of the tab host 37 * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy 38 * view to show as the tab content. It listens to changes in tabs, and takes 39 * care of switch to the correct paged in the ViewPager whenever the selected 40 * tab changes. 41 */ 42 public class TabsAdapter extends PagerAdapter 43 implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener { 44 private final Context mContext; 45 private final TabHost mTabHost; 46 private final ViewPager mViewPager; 47 private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 48 private final Rect mTempRect = new Rect(); 49 private TabHost.OnTabChangeListener mOnTabChangeListener; 50 51 static final class TabInfo { 52 private final String tag; 53 private final View view; 54 55 TabInfo(String _tag, View _view) { 56 tag = _tag; 57 view = _view; 58 } 59 } 60 61 static class DummyTabFactory implements TabHost.TabContentFactory { 62 private final Context mContext; 63 64 public DummyTabFactory(Context context) { 65 mContext = context; 66 } 67 68 @Override 69 public View createTabContent(String tag) { 70 View v = new View(mContext); 71 v.setMinimumWidth(0); 72 v.setMinimumHeight(0); 73 return v; 74 } 75 } 76 77 public TabsAdapter(Activity activity, TabHost tabHost, ViewPager pager) { 78 mContext = activity; 79 mTabHost = tabHost; 80 mViewPager = pager; 81 mTabHost.setOnTabChangedListener(this); 82 mViewPager.setAdapter(this); 83 mViewPager.setOnPageChangeListener(this); 84 } 85 86 public void addTab(TabHost.TabSpec tabSpec, View view) { 87 tabSpec.setContent(new DummyTabFactory(mContext)); 88 String tag = tabSpec.getTag(); 89 90 TabInfo info = new TabInfo(tag, view); 91 mTabs.add(info); 92 mTabHost.addTab(tabSpec); 93 notifyDataSetChanged(); 94 } 95 96 @Override 97 public int getCount() { 98 return mTabs.size(); 99 } 100 101 @Override 102 public Object instantiateItem(ViewGroup container, int position) { 103 View view = mTabs.get(position).view; 104 container.addView(view); 105 return view; 106 } 107 108 @Override 109 public void destroyItem(ViewGroup container, int position, Object object) { 110 container.removeView((View)object); 111 } 112 113 @Override 114 public boolean isViewFromObject(View view, Object object) { 115 return view == object; 116 } 117 118 public void setOnTabChangedListener(TabHost.OnTabChangeListener listener) { 119 mOnTabChangeListener = listener; 120 } 121 122 @Override 123 public void onTabChanged(String tabId) { 124 int position = mTabHost.getCurrentTab(); 125 mViewPager.setCurrentItem(position); 126 if (mOnTabChangeListener != null) { 127 mOnTabChangeListener.onTabChanged(tabId); 128 } 129 } 130 131 @Override 132 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 133 } 134 135 @Override 136 public void onPageSelected(int position) { 137 // Unfortunately when TabHost changes the current tab, it kindly 138 // also takes care of putting focus on it when not in touch mode. 139 // The jerk. 140 // This hack tries to prevent this from pulling focus out of our 141 // ViewPager. 142 TabWidget widget = mTabHost.getTabWidget(); 143 int oldFocusability = widget.getDescendantFocusability(); 144 widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 145 mTabHost.setCurrentTab(position); 146 widget.setDescendantFocusability(oldFocusability); 147 148 // Scroll the current tab into visibility if needed. 149 View tab = widget.getChildTabViewAt(position); 150 mTempRect.set(tab.getLeft(), tab.getTop(), tab.getRight(), tab.getBottom()); 151 widget.requestRectangleOnScreen(mTempRect, false); 152 153 // Make sure the scrollbars are visible for a moment after selection 154 final View contentView = mTabs.get(position).view; 155 if (contentView instanceof CaffeinatedScrollView) { 156 ((CaffeinatedScrollView) contentView).awakenScrollBars(); 157 } 158 } 159 160 @Override 161 public void onPageScrollStateChanged(int state) { 162 } 163 } 164