Swipey tabs
BIN
libs/android-support-v4.jar
Normal file
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 935 B |
Before Width: | Height: | Size: 713 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 831 B |
Before Width: | Height: | Size: 660 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1003 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1003 B |
Before Width: | Height: | Size: 873 B |
Before Width: | Height: | Size: 449 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 998 B |
Before Width: | Height: | Size: 922 B |
BIN
res/drawable-hdpi/vpi__tab_selected_focused_holo.9.png
Normal file
After Width: | Height: | Size: 147 B |
BIN
res/drawable-hdpi/vpi__tab_selected_holo.9.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
res/drawable-hdpi/vpi__tab_selected_pressed_holo.9.png
Normal file
After Width: | Height: | Size: 147 B |
BIN
res/drawable-hdpi/vpi__tab_unselected_focused_holo.9.png
Normal file
After Width: | Height: | Size: 146 B |
BIN
res/drawable-hdpi/vpi__tab_unselected_holo.9.png
Normal file
After Width: | Height: | Size: 153 B |
BIN
res/drawable-hdpi/vpi__tab_unselected_pressed_holo.9.png
Normal file
After Width: | Height: | Size: 145 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 505 B |
Before Width: | Height: | Size: 518 B |
Before Width: | Height: | Size: 1004 B After Width: | Height: | Size: 510 B |
Before Width: | Height: | Size: 472 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 764 B |
Before Width: | Height: | Size: 991 B |
Before Width: | Height: | Size: 642 B |
Before Width: | Height: | Size: 570 B |
Before Width: | Height: | Size: 331 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 586 B |
Before Width: | Height: | Size: 643 B |
BIN
res/drawable-mdpi/vpi__tab_selected_focused_holo.9.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
res/drawable-mdpi/vpi__tab_selected_holo.9.png
Normal file
After Width: | Height: | Size: 151 B |
BIN
res/drawable-mdpi/vpi__tab_selected_pressed_holo.9.png
Normal file
After Width: | Height: | Size: 150 B |
BIN
res/drawable-mdpi/vpi__tab_unselected_focused_holo.9.png
Normal file
After Width: | Height: | Size: 150 B |
BIN
res/drawable-mdpi/vpi__tab_unselected_holo.9.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
res/drawable-mdpi/vpi__tab_unselected_pressed_holo.9.png
Normal file
After Width: | Height: | Size: 155 B |
BIN
res/drawable-xhdpi/ic_tab_albums_selected.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable-xhdpi/ic_tab_artists_selected.png
Normal file
After Width: | Height: | Size: 996 B |
BIN
res/drawable-xhdpi/ic_tab_songs_selected.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-xhdpi/vpi__tab_selected_focused_holo.9.png
Normal file
After Width: | Height: | Size: 147 B |
BIN
res/drawable-xhdpi/vpi__tab_selected_holo.9.png
Normal file
After Width: | Height: | Size: 153 B |
BIN
res/drawable-xhdpi/vpi__tab_selected_pressed_holo.9.png
Normal file
After Width: | Height: | Size: 147 B |
BIN
res/drawable-xhdpi/vpi__tab_unselected_focused_holo.9.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
res/drawable-xhdpi/vpi__tab_unselected_holo.9.png
Normal file
After Width: | Height: | Size: 166 B |
BIN
res/drawable-xhdpi/vpi__tab_unselected_pressed_holo.9.png
Normal file
After Width: | Height: | Size: 149 B |
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_selected="true"
|
||||
android:state_pressed="false"
|
||||
android:drawable="@drawable/ic_tab_albums_selected" />
|
||||
<item
|
||||
android:drawable="@drawable/ic_tab_albums_unselected" />
|
||||
</selector>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_selected="true"
|
||||
android:state_pressed="false"
|
||||
android:drawable="@drawable/ic_tab_artists_selected" />
|
||||
<item
|
||||
android:drawable="@drawable/ic_tab_artists_unselected" />
|
||||
</selector>
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_tab_files_selected" android:state_selected="true" android:state_pressed="false" />
|
||||
<item android:drawable="@drawable/ic_tab_files_unselected" />
|
||||
</selector>
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_tab_genres_selected" android:state_selected="true" android:state_pressed="false" />
|
||||
<item android:drawable="@drawable/ic_tab_genres_unselected" />
|
||||
</selector>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_selected="true"
|
||||
android:state_pressed="false"
|
||||
android:drawable="@drawable/ic_tab_playlists_selected" />
|
||||
<item
|
||||
android:drawable="@drawable/ic_tab_playlists_unselected" />
|
||||
</selector>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_selected="true"
|
||||
android:state_pressed="false"
|
||||
android:drawable="@drawable/ic_tab_songs_selected" />
|
||||
<item
|
||||
android:drawable="@drawable/ic_tab_songs_unselected" />
|
||||
</selector>
|
34
res/drawable/vpi__tab_indicator.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Non focused states -->
|
||||
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/vpi__tab_unselected_holo" />
|
||||
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/vpi__tab_selected_holo" />
|
||||
|
||||
<!-- Focused states -->
|
||||
<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/vpi__tab_unselected_focused_holo" />
|
||||
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/vpi__tab_selected_focused_holo" />
|
||||
|
||||
<!-- Pressed -->
|
||||
<!-- Non focused states -->
|
||||
<item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/vpi__tab_unselected_pressed_holo" />
|
||||
<item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/vpi__tab_selected_pressed_holo" />
|
||||
|
||||
<!-- Focused states -->
|
||||
<item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/vpi__tab_unselected_pressed_holo" />
|
||||
<item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/vpi__tab_selected_pressed_holo" />
|
||||
</selector>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2010 Christopher Eby <kreed@kreed.org>
|
||||
Copyright (C) 2012 Christopher Eby <kreed@kreed.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -20,91 +20,56 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
-->
|
||||
<TabHost
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/tab_host"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/content"
|
||||
android:orientation="vertical"
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/content"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<com.viewpagerindicator.TabPageIndicator
|
||||
android:id="@+id/tabs"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<TabWidget
|
||||
android:id="@android:id/tabs"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<FrameLayout
|
||||
android:id="@android:id/tabcontent"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0px"
|
||||
android:layout_weight="1">
|
||||
<ListView
|
||||
android:id="@+id/artist_list"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
<ListView
|
||||
android:id="@+id/album_list"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
<ListView
|
||||
android:id="@+id/song_list"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
<ListView
|
||||
android:id="@+id/playlist_list"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
<ListView
|
||||
android:id="@+id/genre_list"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
<ListView
|
||||
android:id="@+id/file_list"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
</FrameLayout>
|
||||
<HorizontalScrollView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0px"
|
||||
android:layout_weight="1" />
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/limiter_scroller"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|left">
|
||||
<LinearLayout
|
||||
android:id="@+id/limiter_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent" />
|
||||
</HorizontalScrollView>
|
||||
<LinearLayout
|
||||
android:id="@+id/search_box"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingTop="4dip"
|
||||
android:paddingLeft="4dip"
|
||||
android:visibility="gone"
|
||||
android:background="@drawable/search_background">
|
||||
<EditText
|
||||
android:id="@+id/filter_text"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|left">
|
||||
<LinearLayout
|
||||
android:id="@+id/limiter_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent" />
|
||||
</HorizontalScrollView>
|
||||
<LinearLayout
|
||||
android:id="@+id/search_box"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:paddingTop="4dip"
|
||||
android:layout_weight="1"
|
||||
android:inputType="textFilter" />
|
||||
<ImageButton
|
||||
android:id="@+id/clear_button"
|
||||
android:scaleType="fitCenter"
|
||||
android:paddingLeft="4dip"
|
||||
android:visibility="gone"
|
||||
android:background="@drawable/search_background">
|
||||
<EditText
|
||||
android:id="@+id/filter_text"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:inputType="textFilter" />
|
||||
<ImageButton
|
||||
android:id="@+id/clear_button"
|
||||
android:scaleType="fitCenter"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:paddingBottom="4dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@null"
|
||||
android:src="@drawable/close" />
|
||||
</LinearLayout>
|
||||
android:paddingRight="4dip"
|
||||
android:paddingBottom="4dip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@null"
|
||||
android:src="@drawable/close" />
|
||||
</LinearLayout>
|
||||
</TabHost>
|
||||
</LinearLayout>
|
||||
|
||||
|
205
src/com/viewpagerindicator/TabPageIndicator.java
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
* Copyright (C) 2011 Jake Wharton
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.viewpagerindicator;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import org.kreed.vanilla.R;
|
||||
|
||||
/**
|
||||
* This widget implements the dynamic action bar tab behavior that can change
|
||||
* across different configurations or circumstances.
|
||||
*/
|
||||
public class TabPageIndicator extends HorizontalScrollView
|
||||
implements ViewPager.OnPageChangeListener
|
||||
, View.OnClickListener
|
||||
{
|
||||
Runnable mTabSelector;
|
||||
|
||||
private final LinearLayout mTabLayout;
|
||||
private ViewPager mViewPager;
|
||||
private ViewPager.OnPageChangeListener mListener;
|
||||
|
||||
private int mSelectedTabIndex;
|
||||
|
||||
public TabPageIndicator(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TabPageIndicator(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setHorizontalScrollBarEnabled(false);
|
||||
|
||||
mTabLayout = new LinearLayout(getContext());
|
||||
addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY;
|
||||
setFillViewport(lockedExpanded);
|
||||
|
||||
final int oldWidth = getMeasuredWidth();
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
final int newWidth = getMeasuredWidth();
|
||||
|
||||
if (lockedExpanded && oldWidth != newWidth) {
|
||||
// Recenter the tab display if we're at a new (scrollable) size.
|
||||
setCurrentItem(mSelectedTabIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void animateToTab(final int position) {
|
||||
final View tabView = mTabLayout.getChildAt(position);
|
||||
if (mTabSelector != null) {
|
||||
removeCallbacks(mTabSelector);
|
||||
}
|
||||
mTabSelector = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;
|
||||
smoothScrollTo(scrollPos, 0);
|
||||
mTabSelector = null;
|
||||
}
|
||||
};
|
||||
post(mTabSelector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (mTabSelector != null) {
|
||||
// Re-post the selector we saved
|
||||
post(mTabSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (mTabSelector != null) {
|
||||
removeCallbacks(mTabSelector);
|
||||
}
|
||||
}
|
||||
|
||||
private void addTab(CharSequence text, int index) {
|
||||
Context context = getContext();
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
|
||||
int padX = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 22, dm);
|
||||
int padY = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12, dm);
|
||||
|
||||
TextView tabView = new TextView(context);
|
||||
tabView.setBackgroundResource(R.drawable.vpi__tab_indicator);
|
||||
tabView.setPadding(padX, padY, padX, padY);
|
||||
tabView.setGravity(Gravity.CENTER);
|
||||
tabView.setTextColor(0xfff3f3f3);
|
||||
tabView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
|
||||
tabView.setTypeface(tabView.getTypeface(), Typeface.BOLD);
|
||||
tabView.setSingleLine();
|
||||
tabView.setTag(index);
|
||||
tabView.setFocusable(true);
|
||||
tabView.setOnClickListener(this);
|
||||
tabView.setText(text);
|
||||
|
||||
mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0, LayoutParams.FILL_PARENT, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int arg0) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrollStateChanged(arg0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int arg0, float arg1, int arg2) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrolled(arg0, arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int arg0) {
|
||||
setCurrentItem(arg0);
|
||||
if (mListener != null) {
|
||||
mListener.onPageSelected(arg0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setViewPager(ViewPager view) {
|
||||
final PagerAdapter adapter = view.getAdapter();
|
||||
if (adapter == null) {
|
||||
throw new IllegalStateException("ViewPager does not have adapter instance.");
|
||||
}
|
||||
mViewPager = view;
|
||||
view.setOnPageChangeListener(this);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void notifyDataSetChanged() {
|
||||
mTabLayout.removeAllViews();
|
||||
PagerAdapter adapter = mViewPager.getAdapter();
|
||||
final int count = adapter.getCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
addTab(adapter.getPageTitle(i), i);
|
||||
}
|
||||
if (mSelectedTabIndex > count) {
|
||||
mSelectedTabIndex = count - 1;
|
||||
}
|
||||
setCurrentItem(mSelectedTabIndex);
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
public void setCurrentItem(int item) {
|
||||
if (mViewPager == null) {
|
||||
throw new IllegalStateException("ViewPager has not been bound.");
|
||||
}
|
||||
mSelectedTabIndex = item;
|
||||
final int tabCount = mTabLayout.getChildCount();
|
||||
for (int i = 0; i < tabCount; i++) {
|
||||
final View child = mTabLayout.getChildAt(i);
|
||||
final boolean isSelected = (i == item);
|
||||
child.setSelected(isSelected);
|
||||
if (isSelected) {
|
||||
animateToTab(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mViewPager.setCurrentItem((Integer)view.getTag());
|
||||
}
|
||||
}
|
@ -90,15 +90,9 @@ public final class CoverBitmap {
|
||||
private static void loadIcons(Context context)
|
||||
{
|
||||
Resources res = context.getResources();
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.ic_tab_songs_selected);
|
||||
SONG_ICON = Bitmap.createScaledBitmap(bitmap, TEXT_SIZE, TEXT_SIZE, false);
|
||||
bitmap.recycle();
|
||||
bitmap = BitmapFactory.decodeResource(res, R.drawable.ic_tab_albums_selected);
|
||||
ALBUM_ICON = Bitmap.createScaledBitmap(bitmap, TEXT_SIZE, TEXT_SIZE, false);
|
||||
bitmap.recycle();
|
||||
bitmap = BitmapFactory.decodeResource(res, R.drawable.ic_tab_artists_selected);
|
||||
ARTIST_ICON = Bitmap.createScaledBitmap(bitmap, TEXT_SIZE, TEXT_SIZE, false);
|
||||
bitmap.recycle();
|
||||
SONG_ICON = BitmapFactory.decodeResource(res, R.drawable.ic_tab_songs_selected);
|
||||
ALBUM_ICON = BitmapFactory.decodeResource(res, R.drawable.ic_tab_albums_selected);
|
||||
ARTIST_ICON = BitmapFactory.decodeResource(res, R.drawable.ic_tab_artists_selected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,14 +32,14 @@ import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.PaintDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
@ -55,12 +55,13 @@ import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import com.viewpagerindicator.TabPageIndicator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import junit.framework.Assert;
|
||||
@ -72,9 +73,9 @@ public class LibraryActivity
|
||||
extends PlaybackActivity
|
||||
implements AdapterView.OnItemClickListener
|
||||
, TextWatcher
|
||||
, TabHost.OnTabChangeListener
|
||||
, DialogInterface.OnClickListener
|
||||
, DialogInterface.OnDismissListener
|
||||
, ViewPager.OnPageChangeListener
|
||||
{
|
||||
public static final int ACTION_PLAY = 0;
|
||||
public static final int ACTION_ENQUEUE = 1;
|
||||
@ -87,8 +88,7 @@ public class LibraryActivity
|
||||
{ SongTimeline.MODE_PLAY, SongTimeline.MODE_ENQUEUE, -1,
|
||||
SongTimeline.MODE_PLAY_ID_FIRST, SongTimeline.MODE_ENQUEUE_ID_FIRST };
|
||||
|
||||
private TabHost mTabHost;
|
||||
|
||||
private ViewPager mViewPager;
|
||||
private View mSearchBox;
|
||||
private boolean mSearchBoxVisible;
|
||||
private TextView mTextFilter;
|
||||
@ -100,6 +100,7 @@ public class LibraryActivity
|
||||
private ImageView mCover;
|
||||
private View mEmptyQueue;
|
||||
|
||||
private HorizontalScrollView mLimiterScroller;
|
||||
private ViewGroup mLimiterViews;
|
||||
|
||||
private int mDefaultAction;
|
||||
@ -123,6 +124,15 @@ public class LibraryActivity
|
||||
* Each adapter, in the same order as MediaUtils.TYPE_*.
|
||||
*/
|
||||
final LibraryAdapter[] mAdapters = new LibraryAdapter[ADAPTER_COUNT];
|
||||
/**
|
||||
* The human-readable title for each page.
|
||||
*/
|
||||
public static final int[] TITLES = { R.string.artists, R.string.albums, R.string.songs,
|
||||
R.string.playlists, R.string.genres, R.string.files };
|
||||
/**
|
||||
* Limiters that should be passed to an adapter constructor.
|
||||
*/
|
||||
public final Limiter[] mPendingLimiters = new Limiter[ADAPTER_COUNT];
|
||||
MediaAdapter mArtistAdapter;
|
||||
MediaAdapter mAlbumAdapter;
|
||||
MediaAdapter mSongAdapter;
|
||||
@ -135,7 +145,103 @@ public class LibraryActivity
|
||||
@Override
|
||||
public void onChange(boolean selfChange)
|
||||
{
|
||||
postRequestRequery(mPlaylistAdapter);
|
||||
if (mPlaylistAdapter != null) {
|
||||
postRequestRequery(mPlaylistAdapter);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final PagerAdapter mPagerAdapter = new PagerAdapter() {
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position)
|
||||
{
|
||||
ListView view = mLists[position];
|
||||
|
||||
if (view == null) {
|
||||
LibraryAdapter adapter;
|
||||
|
||||
switch (position) {
|
||||
case 0:
|
||||
adapter = mArtistAdapter = new MediaAdapter(LibraryActivity.this, MediaUtils.TYPE_ARTIST, true, true, null);
|
||||
mArtistAdapter.setHeaderText(getHeaderText());
|
||||
break;
|
||||
case 1:
|
||||
adapter = mAlbumAdapter = new MediaAdapter(LibraryActivity.this, MediaUtils.TYPE_ALBUM, true, true, mPendingLimiters[position]);
|
||||
mAlbumAdapter.setHeaderText(getHeaderText());
|
||||
break;
|
||||
case 2:
|
||||
adapter = mSongAdapter = new MediaAdapter(LibraryActivity.this, MediaUtils.TYPE_SONG, false, true, mPendingLimiters[position]);
|
||||
mSongAdapter.setHeaderText(getHeaderText());
|
||||
break;
|
||||
case 3:
|
||||
adapter = mPlaylistAdapter = new MediaAdapter(LibraryActivity.this, MediaUtils.TYPE_PLAYLIST, true, false, null);
|
||||
break;
|
||||
case 4:
|
||||
adapter = mGenreAdapter = new MediaAdapter(LibraryActivity.this, MediaUtils.TYPE_GENRE, true, false, null);
|
||||
break;
|
||||
case 5:
|
||||
adapter = mFilesAdapter = new FileSystemAdapter(LibraryActivity.this, mPendingLimiters[position]);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid position: " + position);
|
||||
}
|
||||
|
||||
view = new ListView(LibraryActivity.this);
|
||||
view.setOnItemClickListener(LibraryActivity.this);
|
||||
view.setOnCreateContextMenuListener(LibraryActivity.this);
|
||||
view.setDivider(null);
|
||||
view.setFastScrollEnabled(true);
|
||||
|
||||
view.setAdapter(adapter);
|
||||
if (position != 5)
|
||||
loadSortOrder((MediaAdapter)adapter);
|
||||
|
||||
String filter = mTextFilter.getText().toString();
|
||||
if (filter.length() != 0) {
|
||||
adapter.setFilter(filter);
|
||||
}
|
||||
|
||||
mAdapters[position] = adapter;
|
||||
mLists[position] = view;
|
||||
mRequeryNeeded[position] = true;
|
||||
|
||||
if (mCurrentAdapter == null && mViewPager.getCurrentItem() == position) {
|
||||
// Special case: for first time initialization onPageSelected
|
||||
// is not called (for initial position = 0) or called before
|
||||
// the adapter is initialized (for all other initial positions).
|
||||
// So do required work here.
|
||||
mCurrentAdapter = adapter;
|
||||
updateLimiterViews();
|
||||
}
|
||||
}
|
||||
|
||||
requeryIfNeeded(position);
|
||||
container.addView(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object)
|
||||
{
|
||||
container.removeView(mLists[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position)
|
||||
{
|
||||
return getResources().getText(TITLES[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount()
|
||||
{
|
||||
return ADAPTER_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(View view, Object object)
|
||||
{
|
||||
return view == object;
|
||||
}
|
||||
};
|
||||
|
||||
@ -185,44 +291,18 @@ public class LibraryActivity
|
||||
mClearButton = findViewById(R.id.clear_button);
|
||||
mClearButton.setOnClickListener(this);
|
||||
|
||||
mLimiterScroller = (HorizontalScrollView)findViewById(R.id.limiter_scroller);
|
||||
mLimiterViews = (ViewGroup)findViewById(R.id.limiter_layout);
|
||||
|
||||
mTabHost = (TabHost)findViewById(R.id.tab_host);
|
||||
mTabHost.setup();
|
||||
mViewPager = (ViewPager)findViewById(R.id.pager);
|
||||
mViewPager.setAdapter(mPagerAdapter);
|
||||
|
||||
mArtistAdapter = new MediaAdapter(this, MediaUtils.TYPE_ARTIST, true, true, null);
|
||||
mAlbumAdapter = new MediaAdapter(this, MediaUtils.TYPE_ALBUM, true, true, state == null ? null : (Limiter)state.getSerializable("limiter_albums"));
|
||||
mSongAdapter = new MediaAdapter(this, MediaUtils.TYPE_SONG, false, true, state == null ? null : (Limiter)state.getSerializable("limiter_songs"));
|
||||
mPlaylistAdapter = new MediaAdapter(this, MediaUtils.TYPE_PLAYLIST, true, false, null);
|
||||
mGenreAdapter = new MediaAdapter(this, MediaUtils.TYPE_GENRE, true, false, null);
|
||||
mFilesAdapter = new FileSystemAdapter(this, state == null ? null : (Limiter)state.getSerializable("limiter_files"));
|
||||
|
||||
setupView(0, R.id.artist_list, R.string.artists, R.drawable.ic_tab_artists, mArtistAdapter);
|
||||
setupView(1, R.id.album_list, R.string.albums, R.drawable.ic_tab_albums, mAlbumAdapter);
|
||||
setupView(2, R.id.song_list, R.string.songs, R.drawable.ic_tab_songs, mSongAdapter);
|
||||
setupView(3, R.id.playlist_list, R.string.playlists, R.drawable.ic_tab_playlists, mPlaylistAdapter);
|
||||
setupView(4, R.id.genre_list, R.string.genres, R.drawable.ic_tab_genres, mGenreAdapter);
|
||||
setupView(5, R.id.file_list, R.string.files, R.drawable.ic_tab_files, mFilesAdapter);
|
||||
TabPageIndicator tabs = (TabPageIndicator)findViewById(R.id.tabs);
|
||||
tabs.setViewPager(mViewPager);
|
||||
tabs.setOnPageChangeListener(this);
|
||||
|
||||
getContentResolver().registerContentObserver(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, true, mPlaylistObserver);
|
||||
|
||||
int currentTab = 0;
|
||||
String filter = null;
|
||||
|
||||
if (state != null) {
|
||||
if (state.getBoolean("search_box_visible"))
|
||||
setSearchBoxVisible(true);
|
||||
currentTab = state.getInt("current_tab", 0);
|
||||
filter = state.getString("filter");
|
||||
}
|
||||
|
||||
mTabHost.setCurrentTab(currentTab);
|
||||
mTabHost.setOnTabChangedListener(this);
|
||||
onTabChanged(null);
|
||||
|
||||
if (filter != null)
|
||||
mTextFilter.setText(filter);
|
||||
|
||||
onNewIntent(getIntent());
|
||||
}
|
||||
|
||||
@ -256,15 +336,29 @@ public class LibraryActivity
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Bundle in)
|
||||
{
|
||||
super.onRestoreInstanceState(in);
|
||||
if (in.getBoolean("search_box_visible"))
|
||||
setSearchBoxVisible(true);
|
||||
mPendingLimiters[1] = (Limiter)in.getSerializable("limiter_albums");
|
||||
mPendingLimiters[2] = (Limiter)in.getSerializable("limiter_songs");
|
||||
mPendingLimiters[5] = (Limiter)in.getSerializable("limiter_files");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle out)
|
||||
{
|
||||
super.onSaveInstanceState(out);
|
||||
|
||||
out.putBoolean("search_box_visible", mSearchBoxVisible);
|
||||
out.putInt("current_tab", mTabHost.getCurrentTab());
|
||||
out.putString("filter", mTextFilter.getText().toString());
|
||||
out.putSerializable("limiter_albums", mAlbumAdapter.getLimiter());
|
||||
out.putSerializable("limiter_songs", mSongAdapter.getLimiter());
|
||||
out.putSerializable("limiter_files", mFilesAdapter.getLimiter());
|
||||
if (mAlbumAdapter != null)
|
||||
out.putSerializable("limiter_albums", mAlbumAdapter.getLimiter());
|
||||
if (mSongAdapter != null)
|
||||
out.putSerializable("limiter_songs", mSongAdapter.getLimiter());
|
||||
if (mFilesAdapter != null)
|
||||
out.putSerializable("limiter_files", mFilesAdapter.getLimiter());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -306,21 +400,31 @@ public class LibraryActivity
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either "Play All" or "Enqueue All", depending on the current
|
||||
* default action.
|
||||
*/
|
||||
private String getHeaderText()
|
||||
{
|
||||
int action = mDefaultAction;
|
||||
if (action == ACTION_LAST_USED)
|
||||
action = mLastAction;
|
||||
return getString(action == ACTION_ENQUEUE || action == ACTION_ENQUEUE_ALL ? R.string.enqueue_all : R.string.play_all);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the first row of the lists with the appropriate action (play all
|
||||
* or enqueue all).
|
||||
*/
|
||||
private void updateHeaders()
|
||||
{
|
||||
int action = mDefaultAction;
|
||||
if (action == ACTION_LAST_USED)
|
||||
action = mLastAction;
|
||||
|
||||
int res = action == ACTION_ENQUEUE || action == ACTION_ENQUEUE_ALL ? R.string.enqueue_all : R.string.play_all;
|
||||
String text = getString(res);
|
||||
mArtistAdapter.setHeaderText(text);
|
||||
mAlbumAdapter.setHeaderText(text);
|
||||
mSongAdapter.setHeaderText(text);
|
||||
String text = getHeaderText();
|
||||
if (mArtistAdapter != null)
|
||||
mArtistAdapter.setHeaderText(text);
|
||||
if (mAlbumAdapter != null)
|
||||
mAlbumAdapter.setHeaderText(text);
|
||||
if (mSongAdapter != null)
|
||||
mSongAdapter.setHeaderText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -386,15 +490,27 @@ public class LibraryActivity
|
||||
private void clearLimiter(int type)
|
||||
{
|
||||
if (type == MediaUtils.TYPE_FILE) {
|
||||
mFilesAdapter.setLimiter(null);
|
||||
requestRequery(mFilesAdapter);
|
||||
if (mFilesAdapter == null) {
|
||||
mPendingLimiters[5] = null;
|
||||
} else {
|
||||
mFilesAdapter.setLimiter(null);
|
||||
requestRequery(mFilesAdapter);
|
||||
}
|
||||
} else {
|
||||
mAlbumAdapter.setLimiter(null);
|
||||
mSongAdapter.setLimiter(null);
|
||||
loadSortOrder(mSongAdapter);
|
||||
loadSortOrder(mAlbumAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
requestRequery(mAlbumAdapter);
|
||||
if (mAlbumAdapter == null) {
|
||||
mPendingLimiters[1] = null;
|
||||
} else {
|
||||
mAlbumAdapter.setLimiter(null);
|
||||
loadSortOrder(mAlbumAdapter);
|
||||
requestRequery(mAlbumAdapter);
|
||||
}
|
||||
if (mSongAdapter == null) {
|
||||
mPendingLimiters[2] = null;
|
||||
} else {
|
||||
mSongAdapter.setLimiter(null);
|
||||
loadSortOrder(mSongAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
}
|
||||
}
|
||||
updateLimiterViews();
|
||||
}
|
||||
@ -411,40 +527,64 @@ public class LibraryActivity
|
||||
|
||||
switch (limiter.type) {
|
||||
case MediaUtils.TYPE_ALBUM:
|
||||
mSongAdapter.setLimiter(limiter);
|
||||
loadSortOrder(mSongAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
if (mSongAdapter == null) {
|
||||
mPendingLimiters[2] = limiter;
|
||||
} else {
|
||||
mSongAdapter.setLimiter(limiter);
|
||||
loadSortOrder(mSongAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
}
|
||||
tab = 2;
|
||||
break;
|
||||
case MediaUtils.TYPE_ARTIST:
|
||||
mAlbumAdapter.setLimiter(limiter);
|
||||
mSongAdapter.setLimiter(limiter);
|
||||
loadSortOrder(mSongAdapter);
|
||||
loadSortOrder(mAlbumAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
requestRequery(mAlbumAdapter);
|
||||
if (mAlbumAdapter == null) {
|
||||
mPendingLimiters[1] = limiter;
|
||||
} else {
|
||||
mAlbumAdapter.setLimiter(limiter);
|
||||
loadSortOrder(mAlbumAdapter);
|
||||
requestRequery(mAlbumAdapter);
|
||||
}
|
||||
if (mSongAdapter == null) {
|
||||
mPendingLimiters[2] = limiter;
|
||||
} else {
|
||||
mSongAdapter.setLimiter(limiter);
|
||||
loadSortOrder(mSongAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
}
|
||||
tab = 1;
|
||||
break;
|
||||
case MediaUtils.TYPE_GENRE:
|
||||
mSongAdapter.setLimiter(limiter);
|
||||
mAlbumAdapter.setLimiter(null);
|
||||
loadSortOrder(mSongAdapter);
|
||||
loadSortOrder(mAlbumAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
requestRequery(mAlbumAdapter);
|
||||
if (mAlbumAdapter == null) {
|
||||
mPendingLimiters[1] = limiter;
|
||||
} else {
|
||||
mAlbumAdapter.setLimiter(limiter);
|
||||
loadSortOrder(mAlbumAdapter);
|
||||
requestRequery(mAlbumAdapter);
|
||||
}
|
||||
if (mSongAdapter == null) {
|
||||
mPendingLimiters[2] = null;
|
||||
} else {
|
||||
mSongAdapter.setLimiter(limiter);
|
||||
loadSortOrder(mSongAdapter);
|
||||
requestRequery(mSongAdapter);
|
||||
}
|
||||
tab = 2;
|
||||
break;
|
||||
case MediaUtils.TYPE_FILE:
|
||||
mFilesAdapter.setLimiter(limiter);
|
||||
requestRequery(mFilesAdapter);
|
||||
if (mFilesAdapter == null) {
|
||||
mPendingLimiters[5] = limiter;
|
||||
} else {
|
||||
mFilesAdapter.setLimiter(limiter);
|
||||
requestRequery(mFilesAdapter);
|
||||
}
|
||||
tab = 5;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported limiter type: " + limiter.type);
|
||||
}
|
||||
|
||||
if (switchTab && mTabHost.getCurrentTab() != tab) {
|
||||
mTabHost.setCurrentTab(tab);
|
||||
if (switchTab && mViewPager.getCurrentItem() != tab) {
|
||||
mViewPager.setCurrentItem(tab);
|
||||
} else {
|
||||
updateLimiterViews();
|
||||
}
|
||||
@ -499,44 +639,44 @@ public class LibraryActivity
|
||||
{
|
||||
String filter = text.toString();
|
||||
for (LibraryAdapter adapter : mAdapters) {
|
||||
adapter.setFilter(filter);
|
||||
requestRequery(adapter);
|
||||
if (adapter != null) {
|
||||
adapter.setFilter(filter);
|
||||
requestRequery(adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLimiterViews()
|
||||
{
|
||||
if (mLimiterViews == null)
|
||||
return;
|
||||
|
||||
mLimiterViews.removeAllViews();
|
||||
|
||||
LibraryAdapter adapter = mCurrentAdapter;
|
||||
if (adapter == null)
|
||||
return;
|
||||
Limiter limiterData;
|
||||
if (adapter != null && (limiterData = adapter.getLimiter()) != null) {
|
||||
String[] limiter = limiterData.names;
|
||||
|
||||
Limiter limiterData = adapter.getLimiter();
|
||||
if (limiterData == null)
|
||||
return;
|
||||
String[] limiter = limiterData.names;
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
params.leftMargin = 5;
|
||||
for (int i = 0; i != limiter.length; ++i) {
|
||||
PaintDrawable background = new PaintDrawable(Color.GRAY);
|
||||
background.setCornerRadius(5);
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
params.leftMargin = 5;
|
||||
for (int i = 0; i != limiter.length; ++i) {
|
||||
PaintDrawable background = new PaintDrawable(Color.GRAY);
|
||||
background.setCornerRadius(5);
|
||||
TextView view = new TextView(this);
|
||||
view.setSingleLine();
|
||||
view.setEllipsize(TextUtils.TruncateAt.MARQUEE);
|
||||
view.setText(limiter[i] + " | X");
|
||||
view.setTextColor(Color.WHITE);
|
||||
view.setBackgroundDrawable(background);
|
||||
view.setLayoutParams(params);
|
||||
view.setPadding(5, 2, 5, 2);
|
||||
view.setTag(i);
|
||||
view.setOnClickListener(this);
|
||||
mLimiterViews.addView(view);
|
||||
}
|
||||
|
||||
TextView view = new TextView(this);
|
||||
view.setSingleLine();
|
||||
view.setEllipsize(TextUtils.TruncateAt.MARQUEE);
|
||||
view.setText(limiter[i] + " | X");
|
||||
view.setTextColor(Color.WHITE);
|
||||
view.setBackgroundDrawable(background);
|
||||
view.setLayoutParams(params);
|
||||
view.setPadding(5, 2, 5, 2);
|
||||
view.setTag(i);
|
||||
view.setOnClickListener(this);
|
||||
mLimiterViews.addView(view);
|
||||
mLimiterScroller.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mLimiterScroller.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -891,40 +1031,6 @@ public class LibraryActivity
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook up a ListView to this Activity and the supplied adapter
|
||||
*
|
||||
* @param index Where to put the view and adapter in mLists/mAdapters.
|
||||
* @param id The id of the ListView
|
||||
* @param adapter The adapter to hook up.
|
||||
* @param label The text to show on the tab.
|
||||
* @param icon The icon to show on the tab.
|
||||
*/
|
||||
private void setupView(int index, int id, int label, int icon, LibraryAdapter adapter)
|
||||
{
|
||||
ListView view = (ListView)findViewById(id);
|
||||
view.setOnItemClickListener(this);
|
||||
view.setOnCreateContextMenuListener(this);
|
||||
view.setDivider(null);
|
||||
view.setFastScrollEnabled(true);
|
||||
|
||||
view.setAdapter(adapter);
|
||||
if (adapter instanceof MediaAdapter)
|
||||
loadSortOrder((MediaAdapter)adapter);
|
||||
|
||||
Resources res = getResources();
|
||||
String labelRes = res.getString(label);
|
||||
Drawable iconRes = res.getDrawable(icon);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
mTabHost.addTab(mTabHost.newTabSpec(labelRes).setIndicator(null, iconRes).setContent(id));
|
||||
else
|
||||
mTabHost.addTab(mTabHost.newTabSpec(labelRes).setIndicator(labelRes, iconRes).setContent(id));
|
||||
|
||||
mAdapters[index] = adapter;
|
||||
mLists[index] = view;
|
||||
mRequeryNeeded[index] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call addToPlaylist with the results from a NewPlaylistDialog stored in
|
||||
* obj.
|
||||
@ -1055,7 +1161,9 @@ public class LibraryActivity
|
||||
public void onMediaChange()
|
||||
{
|
||||
for (LibraryAdapter adapter : mAdapters) {
|
||||
postRequestRequery(adapter);
|
||||
if (adapter != null) {
|
||||
postRequestRequery(adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1124,17 +1232,6 @@ public class LibraryActivity
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabChanged(String tag)
|
||||
{
|
||||
LibraryAdapter adapter = mAdapters[mTabHost.getCurrentTab()];
|
||||
mCurrentAdapter = adapter;
|
||||
if (mRequeryNeeded[adapter.getMediaType() - 1]) {
|
||||
runQuery(adapter);
|
||||
}
|
||||
updateLimiterViews();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the saved sort mode for the given adapter. The adapter should
|
||||
* be re-queried after calling this.
|
||||
@ -1173,10 +1270,45 @@ public class LibraryActivity
|
||||
|
||||
// Force a new FastScroller to be created so the scroll sections
|
||||
// are updated.
|
||||
ListView view = (ListView)mTabHost.getCurrentView();
|
||||
ListView view = mLists[mViewPager.getCurrentItem()];
|
||||
view.setFastScrollEnabled(false);
|
||||
view.setFastScrollEnabled(true);
|
||||
|
||||
mHandler.sendMessage(mHandler.obtainMessage(MSG_SAVE_SORT, adapter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Requery the adapter at the given position if it exists and needs a requery.
|
||||
*
|
||||
* @param position An index in mAdapters.
|
||||
*/
|
||||
public void requeryIfNeeded(int position)
|
||||
{
|
||||
LibraryAdapter adapter = mAdapters[position];
|
||||
if (adapter != null && mRequeryNeeded[position]) {
|
||||
runQuery(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int arg0)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int arg0, float arg1, int arg2)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position)
|
||||
{
|
||||
mCurrentAdapter = mAdapters[position];
|
||||
requeryIfNeeded(position);
|
||||
if (position < ADAPTER_COUNT - 1)
|
||||
requeryIfNeeded(position + 1);
|
||||
if (position > 0)
|
||||
requeryIfNeeded(position - 1);
|
||||
updateLimiterViews();
|
||||
}
|
||||
}
|
||||
|