1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.messaging.ui; 17 18 import android.content.Context; 19 import android.database.Cursor; 20 import android.view.LayoutInflater; 21 import android.view.View; 22 import android.view.ViewGroup; 23 import android.widget.AbsListView; 24 import android.widget.AbsListView.OnScrollListener; 25 import android.widget.CursorAdapter; 26 import android.widget.ListView; 27 28 import com.android.messaging.util.ImeUtil; 29 30 /** 31 * Produces and holds a list view and its tab header to be displayed in a ViewPager. 32 */ 33 public abstract class CustomHeaderPagerListViewHolder extends BasePagerViewHolder 34 implements CustomHeaderPagerViewHolder { 35 private final Context mContext; 36 private final CursorAdapter mListAdapter; 37 private boolean mListCursorInitialized; 38 private ListView mListView; 39 CustomHeaderPagerListViewHolder(final Context context, final CursorAdapter adapter)40 public CustomHeaderPagerListViewHolder(final Context context, 41 final CursorAdapter adapter) { 42 mContext = context; 43 mListAdapter = adapter; 44 } 45 46 @Override createView(ViewGroup container)47 protected View createView(ViewGroup container) { 48 final LayoutInflater inflater = (LayoutInflater) 49 mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 50 final View view = inflater.inflate( 51 getLayoutResId(), 52 null /* root */, 53 false /* attachToRoot */); 54 final ListView listView = (ListView) view.findViewById(getListViewResId()); 55 listView.setAdapter(mListAdapter); 56 listView.setOnScrollListener(new OnScrollListener() { 57 @Override 58 public void onScrollStateChanged(final AbsListView view, final int scrollState) { 59 if (scrollState != SCROLL_STATE_IDLE) { 60 ImeUtil.get().hideImeKeyboard(mContext, view); 61 } 62 } 63 64 @Override 65 public void onScroll(final AbsListView view, final int firstVisibleItem, 66 final int visibleItemCount, final int totalItemCount) { 67 } 68 }); 69 mListView = listView; 70 maybeSetEmptyView(); 71 return view; 72 } 73 onContactsCursorUpdated(final Cursor data)74 public void onContactsCursorUpdated(final Cursor data) { 75 mListAdapter.swapCursor(data); 76 if (!mListCursorInitialized) { 77 // We set the emptyView here instead of in create so that the initial load won't show 78 // the empty UI - the system handles this and doesn't do what we would like. 79 mListCursorInitialized = true; 80 maybeSetEmptyView(); 81 } 82 } 83 84 /** 85 * We don't want to show the empty view hint until BOTH conditions are met: 86 * 1. The view has been created. 87 * 2. Cursor data has been loaded once. 88 * Due to timing when data is loaded, the view may not be ready (and vice versa). So we 89 * are calling this method from both onContactsCursorUpdated & createView. 90 */ maybeSetEmptyView()91 private void maybeSetEmptyView() { 92 if (mView != null && mListCursorInitialized) { 93 final ListEmptyView emptyView = (ListEmptyView) mView.findViewById(getEmptyViewResId()); 94 if (emptyView != null) { 95 emptyView.setTextHint(getEmptyViewTitleResId()); 96 emptyView.setImageHint(getEmptyViewImageResId()); 97 final ListView listView = (ListView) mView.findViewById(getListViewResId()); 98 listView.setEmptyView(emptyView); 99 } 100 } 101 } 102 invalidateList()103 public void invalidateList() { 104 mListAdapter.notifyDataSetChanged(); 105 } 106 107 /** 108 * In order for scene transition to work, we toggle the visibility for each individual list 109 * view items so that they can be properly tracked by the scene transition manager. 110 * @param show whether the pending transition is to show or hide the list. 111 */ toggleVisibilityForPendingTransition(final boolean show, final View epicenterView)112 public void toggleVisibilityForPendingTransition(final boolean show, final View epicenterView) { 113 if (mListView == null) { 114 return; 115 } 116 final int childCount = mListView.getChildCount(); 117 for (int i = 0; i < childCount; i++) { 118 final View childView = mListView.getChildAt(i); 119 if (childView != epicenterView) { 120 childView.setVisibility(show ? View.VISIBLE : View.INVISIBLE); 121 } 122 } 123 } 124 125 @Override getPageTitle(Context context)126 public CharSequence getPageTitle(Context context) { 127 return context.getString(getPageTitleResId()); 128 } 129 getLayoutResId()130 protected abstract int getLayoutResId(); getPageTitleResId()131 protected abstract int getPageTitleResId(); getEmptyViewResId()132 protected abstract int getEmptyViewResId(); getEmptyViewTitleResId()133 protected abstract int getEmptyViewTitleResId(); getEmptyViewImageResId()134 protected abstract int getEmptyViewImageResId(); getListViewResId()135 protected abstract int getListViewResId(); 136 } 137