19f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas/* 29f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * Copyright (C) 2011 The Android Open Source Project 39f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * 49f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * Licensed under the Apache License, Version 2.0 (the "License"); 59f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * you may not use this file except in compliance with the License. 69f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * You may obtain a copy of the License at 79f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * 89f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * http://www.apache.org/licenses/LICENSE-2.0 99f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * 109f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * Unless required by applicable law or agreed to in writing, software 119f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * distributed under the License is distributed on an "AS IS" BASIS, 129f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * See the License for the specific language governing permissions and 149f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas * limitations under the License. 159f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas */ 169f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 179f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucaspackage com.example.android.hcgallery; 189f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 19ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainimport android.app.ActionBar; 20ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainimport android.app.Activity; 21ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainimport android.app.FragmentTransaction; 229f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.app.ListFragment; 239f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.content.ClipData; 24f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurikimport android.content.res.TypedArray; 259f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.graphics.Canvas; 269f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.graphics.Color; 279f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.graphics.drawable.Drawable; 289f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.os.Bundle; 299f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.view.View; 30ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainimport android.view.ViewTreeObserver; 319f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.widget.AdapterView; 32ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainimport android.widget.AdapterView.OnItemLongClickListener; 339f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.widget.ArrayAdapter; 34ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainimport android.widget.FrameLayout; 35ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainimport android.widget.FrameLayout.LayoutParams; 369f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.widget.ListView; 379f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucasimport android.widget.TextView; 389f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 39ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main/** 40ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * Fragment that shows the list of images 41ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * As an extension of ListFragment, this fragment uses a default layout 42ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * that includes a single ListView, which you can acquire with getListView() 43ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * When running on a screen size smaller than "large", this fragment appears alone 44ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * in MainActivity. In this case, selecting a list item opens the ContentActivity, 45ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * which likewise holds only the ContentFragment. 46ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main */ 47ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Mainpublic class TitlesFragment extends ListFragment implements ActionBar.TabListener { 48ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main OnItemSelectedListener mListener; 499f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas private int mCategory = 0; 509f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas private int mCurPosition = 0; 51ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main private boolean mDualFragments = false; 52ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 53ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main /** Container Activity must implement this interface and we ensure 54ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * that it does during the onAttach() callback 55ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main */ 56ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public interface OnItemSelectedListener { 57ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onItemSelected(int category, int position); 58ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 599f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 609f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas @Override 61ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onAttach(Activity activity) { 62ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main super.onAttach(activity); 63ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Check that the container activity has implemented the callback interface 64ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main try { 65ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main mListener = (OnItemSelectedListener) activity; 66ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } catch (ClassCastException e) { 67ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main throw new ClassCastException(activity.toString() 68ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main + " must implement OnItemSelectedListener"); 69ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 70ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 71ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 72ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main /** This is where we perform setup for the fragment that's either 73ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * not related to the fragment's layout or must be done after the layout is drawn. 74ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * Notice that this fragment does not implement onCreateView(), because it extends 75ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * ListFragment, which includes a ListView as the root view by default, so there's 76ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * no need to set up the layout. 77ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main */ 78ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main @Override 799f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas public void onActivityCreated(Bundle savedInstanceState) { 809f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas super.onActivityCreated(savedInstanceState); 819f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 82ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main ContentFragment frag = (ContentFragment) getFragmentManager() 83ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main .findFragmentById(R.id.content_frag); 84ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main if (frag != null) mDualFragments = true; 85ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 86ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main ActionBar bar = getActivity().getActionBar(); 87ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main bar.setDisplayHomeAsUpEnabled(false); 88ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 89ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 90ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Must call in order to get callback to onCreateOptionsMenu() 91ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main setHasOptionsMenu(true); 92ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 93ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main Directory.initializeDirectory(); 94ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main for (int i = 0; i < Directory.getCategoryCount(); i++) { 95ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName()) 96ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main .setTabListener(this)); 97ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 98ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 999f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas //Current position should survive screen rotations. 1009f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas if (savedInstanceState != null) { 1019f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas mCategory = savedInstanceState.getInt("category"); 1029f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas mCurPosition = savedInstanceState.getInt("listPosition"); 103ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main bar.selectTab(bar.getTabAt(mCategory)); 1049f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 1059f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 1069f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas populateTitles(mCategory); 1079f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas ListView lv = getListView(); 108ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main lv.setCacheColorHint(Color.TRANSPARENT); // Improves scrolling performance 109ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 110ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main if (mDualFragments) { 111ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Highlight the currently selected item 112ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 113ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Enable drag and dropping 114ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main lv.setOnItemLongClickListener(new OnItemLongClickListener() { 115ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) { 116ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main final String title = (String) ((TextView) v).getText(); 117ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 118ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Set up clip data with the category||entry_id format. 119ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main final String textData = String.format("%d||%d", mCategory, pos); 120ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main ClipData data = ClipData.newPlainText(title, textData); 121ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main v.startDrag(data, new MyDragShadowBuilder(v), null, 0); 122ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main return true; 123ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 124ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main }); 125ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 126ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 127ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // If showing both fragments, select the appropriate list item by default 128ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main if (mDualFragments) selectPosition(mCurPosition); 129ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 130ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Attach a GlobalLayoutListener so that we get a callback when the layout 131ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // has finished drawing. This is necessary so that we can apply top-margin 132ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // to the ListView in order to dodge the ActionBar. Ordinarily, that's not 133ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // necessary, but we've set the ActionBar to "overlay" mode using our theme, 134ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // so the layout does not account for the action bar position on its own. 135ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main ViewTreeObserver observer = getListView().getViewTreeObserver(); 136ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main observer.addOnGlobalLayoutListener(layoutListener); 137ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 138f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik 139ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main @Override 140ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onDestroyView() { 141ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main super.onDestroyView(); 142ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Always detach ViewTreeObserver listeners when the view tears down 143ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main getListView().getViewTreeObserver().removeGlobalOnLayoutListener(layoutListener); 1449f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 1459f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 146ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main /** Attaches an adapter to the fragment's ListView to populate it with items */ 147ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void populateTitles(int category) { 148ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main DirectoryCategory cat = Directory.getCategory(category); 149ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main String[] items = new String[cat.getEntryCount()]; 150ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main for (int i = 0; i < cat.getEntryCount(); i++) 151ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main items[i] = cat.getEntry(i).getName(); 152ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Convenience method to attach an adapter to ListFragment's ListView 153ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main setListAdapter(new ArrayAdapter<String>(getActivity(), 154ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main R.layout.title_list_item, items)); 155ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main mCategory = category; 156ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 157ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 158ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main @Override 159ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onListItemClick(ListView l, View v, int position, long id) { 160ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Send the event to the host activity via OnItemSelectedListener callback 161ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main mListener.onItemSelected(mCategory, position); 162ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main mCurPosition = position; 163ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 164ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 165ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main /** Called to select an item from the listview */ 166ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void selectPosition(int position) { 167ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Only if we're showing both fragments should the item be "highlighted" 168ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main if (mDualFragments) { 169ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main ListView lv = getListView(); 170ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main lv.setItemChecked(position, true); 171ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 172ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Calls the parent activity's implementation of the OnItemSelectedListener 173ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // so the activity can pass the event to the sibling fragment as appropriate 174ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main mListener.onItemSelected(mCategory, position); 175ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 176ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 177ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main @Override 178ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onSaveInstanceState (Bundle outState) { 179ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main super.onSaveInstanceState(outState); 180ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main outState.putInt("listPosition", mCurPosition); 181ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main outState.putInt("category", mCategory); 182ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 183ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 184ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main /** This defines how the draggable list items appear during a drag event */ 185f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik private class MyDragShadowBuilder extends View.DragShadowBuilder { 186f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik private Drawable mShadow; 187f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik 188f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik public MyDragShadowBuilder(View v) { 1899f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas super(v); 190f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik 191f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik final TypedArray a = v.getContext().obtainStyledAttributes(R.styleable.AppTheme); 192f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik mShadow = a.getDrawable(R.styleable.AppTheme_listDragShadowBackground); 193f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik mShadow.setCallback(v); 194821736e1fb70be2c827c9e6a35a7739762523897Alexander Lucas mShadow.setBounds(0, 0, v.getWidth(), v.getHeight()); 195f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik a.recycle(); 1969f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 1979f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 1989f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas @Override 1999f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas public void onDrawShadow(Canvas canvas) { 200821736e1fb70be2c827c9e6a35a7739762523897Alexander Lucas super.onDrawShadow(canvas); 201821736e1fb70be2c827c9e6a35a7739762523897Alexander Lucas mShadow.draw(canvas); 202f4f345d0b75c96d92f15a9aba8d58d5d4bec27c6Roman Nurik getView().draw(canvas); 2039f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 2049f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 2059f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 206ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // Because the fragment doesn't have a reliable callback to notify us when 207ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // the activity's layout is completely drawn, this OnGlobalLayoutListener provides 208ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // the necessary callback so we can add top-margin to the ListView in order to dodge 209ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // the ActionBar. Which is necessary because the ActionBar is in overlay mode, meaning 210ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // that it will ordinarily sit on top of the activity layout as a top layer and 211ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // the ActionBar height can vary. Specifically, when on a small/normal size screen, 212ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // the action bar tabs appear in a second row, making the action bar twice as tall. 213ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main ViewTreeObserver.OnGlobalLayoutListener layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { 214ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main @Override 215ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onGlobalLayout() { 216ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main int barHeight = getActivity().getActionBar().getHeight(); 217ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main ListView listView = getListView(); 218ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main FrameLayout.LayoutParams params = (LayoutParams) listView.getLayoutParams(); 219ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // The list view top-margin should always match the action bar height 220ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main if (params.topMargin != barHeight) { 221ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main params.topMargin = barHeight; 222ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main listView.setLayoutParams(params); 223ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 224ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main // The action bar doesn't update its height when hidden, so make top-margin zero 225ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main if (!getActivity().getActionBar().isShowing()) { 226ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main params.topMargin = 0; 227ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main listView.setLayoutParams(params); 228ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 229ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 230ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main }; 2319f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 2329f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 233ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main /* The following are callbacks implemented for the ActionBar.TabListener, 234ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main * which this fragment implements to handle events when tabs are selected. 235ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main */ 236ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 237ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { 238ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main TitlesFragment titleFrag = (TitlesFragment) getFragmentManager() 239ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main .findFragmentById(R.id.titles_frag); 240ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main titleFrag.populateTitles(tab.getPosition()); 241ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 242ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main if (mDualFragments) { 243ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main titleFrag.selectPosition(0); 244ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main } 2459f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 2469f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 247ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main /* These must be implemented, but we don't use them */ 248ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 249ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { 2509f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 2519f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas 252ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { 2539f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas } 254ddd0d0c656c64b463491d750fadbedf3d682b2a1Scott Main 2559f935c7da5a0111f8ee0d2f7c59e6c1695916053Alexander Lucas} 256