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*/ 17package com.android.packageinstaller; 18 19import android.app.Activity; 20import android.content.Context; 21import android.graphics.Rect; 22import android.support.v4.view.PagerAdapter; 23import android.support.v4.view.ViewPager; 24import android.view.View; 25import android.view.ViewGroup; 26import android.widget.TabHost; 27import android.widget.TabWidget; 28 29import 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 */ 42public 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 50 static final class TabInfo { 51 private final String tag; 52 private final View view; 53 54 TabInfo(String _tag, View _view) { 55 tag = _tag; 56 view = _view; 57 } 58 } 59 60 static class DummyTabFactory implements TabHost.TabContentFactory { 61 private final Context mContext; 62 63 public DummyTabFactory(Context context) { 64 mContext = context; 65 } 66 67 @Override 68 public View createTabContent(String tag) { 69 View v = new View(mContext); 70 v.setMinimumWidth(0); 71 v.setMinimumHeight(0); 72 return v; 73 } 74 } 75 76 public TabsAdapter(Activity activity, TabHost tabHost, ViewPager pager) { 77 mContext = activity; 78 mTabHost = tabHost; 79 mViewPager = pager; 80 mTabHost.setOnTabChangedListener(this); 81 mViewPager.setAdapter(this); 82 mViewPager.setOnPageChangeListener(this); 83 } 84 85 public void addTab(TabHost.TabSpec tabSpec, View view) { 86 tabSpec.setContent(new DummyTabFactory(mContext)); 87 String tag = tabSpec.getTag(); 88 89 TabInfo info = new TabInfo(tag, view); 90 mTabs.add(info); 91 mTabHost.addTab(tabSpec); 92 notifyDataSetChanged(); 93 } 94 95 @Override 96 public int getCount() { 97 return mTabs.size(); 98 } 99 100 @Override 101 public Object instantiateItem(ViewGroup container, int position) { 102 View view = mTabs.get(position).view; 103 container.addView(view); 104 return view; 105 } 106 107 @Override 108 public void destroyItem(ViewGroup container, int position, Object object) { 109 container.removeView((View)object); 110 } 111 112 @Override 113 public boolean isViewFromObject(View view, Object object) { 114 return view == object; 115 } 116 117 @Override 118 public void onTabChanged(String tabId) { 119 int position = mTabHost.getCurrentTab(); 120 mViewPager.setCurrentItem(position); 121 } 122 123 @Override 124 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 125 } 126 127 @Override 128 public void onPageSelected(int position) { 129 // Unfortunately when TabHost changes the current tab, it kindly 130 // also takes care of putting focus on it when not in touch mode. 131 // The jerk. 132 // This hack tries to prevent this from pulling focus out of our 133 // ViewPager. 134 TabWidget widget = mTabHost.getTabWidget(); 135 int oldFocusability = widget.getDescendantFocusability(); 136 widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 137 mTabHost.setCurrentTab(position); 138 widget.setDescendantFocusability(oldFocusability); 139 140 // Scroll the current tab into visibility if needed. 141 View tab = widget.getChildTabViewAt(position); 142 mTempRect.set(tab.getLeft(), tab.getTop(), tab.getRight(), tab.getBottom()); 143 widget.requestRectangleOnScreen(mTempRect, false); 144 145 // Make sure the scrollbars are visible for a moment after selection 146 final View contentView = mTabs.get(position).view; 147 if (contentView instanceof CaffeinatedScrollView) { 148 ((CaffeinatedScrollView) contentView).awakenScrollBars(); 149 } 150 } 151 152 @Override 153 public void onPageScrollStateChanged(int state) { 154 } 155} 156