Remove MergeAdapter and SackOfViewsAdapter

This commit is contained in:
tzugen 2021-12-07 10:18:26 +01:00
parent eb2aeabd5d
commit 28d5e5043f
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
5 changed files with 331 additions and 756 deletions

View File

@ -1,316 +0,0 @@
/**
Copyright (c) 2008-2009 CommonsWare, LLC
Portions (c) 2009 Google, Inc.
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 org.moire.ultrasonic.util;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Adapter that merges multiple child adapters and views
* into a single contiguous whole.
* <p/>
* Adapters used as pieces within MergeAdapter must
* have view type IDs monotonically increasing from 0. Ideally,
* adapters also have distinct ranges for their row ids, as
* returned by getItemId().
*/
public class MergeAdapter extends BaseAdapter
{
private final CascadeDataSetObserver observer = new CascadeDataSetObserver();
private final AbstractList<ListAdapter> pieces = new ArrayList<ListAdapter>();
/**
* Adds a new adapter to the roster of things to appear
* in the aggregate list.
*
* @param adapter Source for row views for this section
*/
public void addAdapter(ListAdapter adapter)
{
pieces.add(adapter);
adapter.registerDataSetObserver(observer);
}
public void removeAdapter(ListAdapter adapter)
{
adapter.unregisterDataSetObserver(observer);
pieces.remove(adapter);
}
/**
* Adds a new View to the roster of things to appear
* in the aggregate list.
*
* @param view Single view to add
*/
public ListAdapter addView(View view)
{
return addView(view, false);
}
/**
* Adds a new View to the roster of things to appear
* in the aggregate list.
*
* @param view Single view to add
* @param enabled false if views are disabled, true if enabled
*/
public ListAdapter addView(View view, boolean enabled)
{
return addViews(Collections.singletonList(view), enabled);
}
/**
* Adds a list of views to the roster of things to appear
* in the aggregate list.
*
* @param views List of views to add
*/
public ListAdapter addViews(List<View> views)
{
return addViews(views, false);
}
/**
* Adds a list of views to the roster of things to appear
* in the aggregate list.
*
* @param views List of views to add
* @param enabled false if views are disabled, true if enabled
*/
public ListAdapter addViews(List<View> views, boolean enabled)
{
ListAdapter adapter = enabled ? new EnabledSackAdapter(views) : new SackOfViewsAdapter(views);
addAdapter(adapter);
return adapter;
}
/**
* Get the data item associated with the specified
* position in the data set.
*
* @param position Position of the item whose data we want
*/
@Override
public Object getItem(int position)
{
for (ListAdapter piece : pieces)
{
int size = piece.getCount();
if (position < size)
{
return (piece.getItem(position));
}
position -= size;
}
return (null);
}
/**
* How many items are in the data set represented by this
* Adapter.
*/
@Override
public int getCount()
{
int total = 0;
for (ListAdapter piece : pieces)
{
total += piece.getCount();
}
return (total);
}
/**
* Returns the number of types of Views that will be
* created by getView().
*/
@Override
public int getViewTypeCount()
{
int total = 0;
for (ListAdapter piece : pieces)
{
total += piece.getViewTypeCount();
}
return (Math.max(total, 1)); // needed for setListAdapter() before content add'
}
/**
* Get the type of View that will be created by getView()
* for the specified item.
*
* @param position Position of the item whose data we want
*/
@Override
public int getItemViewType(int position)
{
int typeOffset = 0;
int result = -1;
for (ListAdapter piece : pieces)
{
int size = piece.getCount();
if (position < size)
{
result = typeOffset + piece.getItemViewType(position);
break;
}
position -= size;
typeOffset += piece.getViewTypeCount();
}
return (result);
}
/**
* Are all items in this ListAdapter enabled? If yes it
* means all items are selectable and clickable.
*/
@Override
public boolean areAllItemsEnabled()
{
return (false);
}
/**
* Returns true if the item at the specified position is
* not a separator.
*
* @param position Position of the item whose data we want
*/
@Override
public boolean isEnabled(int position)
{
for (ListAdapter piece : pieces)
{
int size = piece.getCount();
if (position < size)
{
return (piece.isEnabled(position));
}
position -= size;
}
return (false);
}
/**
* Get a View that displays the data at the specified
* position in the data set.
*
* @param position Position of the item whose data we want
* @param convertView View to recycle, if not null
* @param parent ViewGroup containing the returned View
*/
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
for (ListAdapter piece : pieces)
{
int size = piece.getCount();
if (position < size)
{
return (piece.getView(position, convertView, parent));
}
position -= size;
}
return (null);
}
/**
* Get the row id associated with the specified position
* in the list.
*
* @param position Position of the item whose data we want
*/
@Override
public long getItemId(int position)
{
for (ListAdapter piece : pieces)
{
int size = piece.getCount();
if (position < size)
{
return (piece.getItemId(position));
}
position -= size;
}
return (-1);
}
private static class EnabledSackAdapter extends SackOfViewsAdapter
{
public EnabledSackAdapter(List<View> views)
{
super(views);
}
@Override
public boolean areAllItemsEnabled()
{
return (true);
}
@Override
public boolean isEnabled(int position)
{
return (true);
}
}
private class CascadeDataSetObserver extends DataSetObserver
{
@Override
public void onChanged()
{
notifyDataSetChanged();
}
@Override
public void onInvalidated()
{
notifyDataSetInvalidated();
}
}
}

View File

@ -1,195 +0,0 @@
/**
Copyright (c) 2008-2009 CommonsWare, LLC
Portions (c) 2009 Google, Inc.
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 org.moire.ultrasonic.util;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
/**
* Adapter that simply returns row views from a list.
* <p/>
* If you supply a size, you must implement newView(), to
* create a required view. The adapter will then cache these
* views.
* <p/>
* If you supply a list of views in the constructor, that
* list will be used directly. If any elements in the list
* are null, then newView() will be called just for those
* slots.
* <p/>
* Subclasses may also wish to override areAllItemsEnabled()
* (default: false) and isEnabled() (default: false), if some
* of their rows should be selectable.
* <p/>
* It is assumed each view is unique, and therefore will not
* get recycled.
* <p/>
* Note that this adapter is not designed for long lists. It
* is more for screens that should behave like a list. This
* is particularly useful if you combine this with other
* adapters (e.g., SectionedAdapter) that might have an
* arbitrary number of rows, so it all appears seamless.
*/
public class SackOfViewsAdapter extends BaseAdapter
{
private List<View> views;
/**
* Constructor creating an empty list of views, but with
* a specified count. Subclasses must override newView().
*/
public SackOfViewsAdapter(int count)
{
super();
views = new ArrayList<View>(count);
for (int i = 0; i < count; i++)
{
views.add(null);
}
}
/**
* Constructor wrapping a supplied list of views.
* Subclasses must override newView() if any of the elements
* in the list are null.
*/
public SackOfViewsAdapter(List<View> views)
{
for (View view : views)
{
view.setLayoutParams(new ListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
this.views = views;
}
/**
* Get the data item associated with the specified
* position in the data set.
*
* @param position Position of the item whose data we want
*/
@Override
public Object getItem(int position)
{
return (views.get(position));
}
/**
* How many items are in the data set represented by this
* Adapter.
*/
@Override
public int getCount()
{
return (views.size());
}
/**
* Returns the number of types of Views that will be
* created by getView().
*/
@Override
public int getViewTypeCount()
{
return (getCount());
}
/**
* Get the type of View that will be created by getView()
* for the specified item.
*
* @param position Position of the item whose data we want
*/
@Override
public int getItemViewType(int position)
{
return (position);
}
/**
* Are all items in this ListAdapter enabled? If yes it
* means all items are selectable and clickable.
*/
@Override
public boolean areAllItemsEnabled()
{
return (false);
}
/**
* Returns true if the item at the specified position is
* not a separator.
*
* @param position Position of the item whose data we want
*/
@Override
public boolean isEnabled(int position)
{
return (false);
}
/**
* Get a View that displays the data at the specified
* position in the data set.
*
* @param position Position of the item whose data we want
* @param convertView View to recycle, if not null
* @param parent ViewGroup containing the returned View
*/
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View result = views.get(position);
if (result == null)
{
result = newView(position, parent);
views.set(position, result);
}
return (result);
}
/**
* Get the row id associated with the specified position
* in the list.
*
* @param position Position of the item whose data we want
*/
@Override
public long getItemId(int position)
{
return (position);
}
/**
* Create a new View to go into the list at the specified
* position.
*
* @param position Position of the item whose data we want
* @param parent ViewGroup containing the returned View
*/
protected static View newView(int position, ViewGroup parent)
{
throw new RuntimeException("You must override newView()!");
}
}

View File

@ -4,16 +4,15 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import org.koin.core.component.KoinComponent
import org.moire.ultrasonic.R
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.MergeAdapter
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Util
@ -21,26 +20,26 @@ import org.moire.ultrasonic.util.Util
* Displays the Main screen of Ultrasonic, where the music library can be browsed
*/
class MainFragment : Fragment(), KoinComponent {
private var list: ListView? = null
private lateinit var musicTitle: View
private lateinit var artistsButton: View
private lateinit var albumsButton: View
private lateinit var genresButton: View
private lateinit var videosTitle: View
private lateinit var songsTitle: View
private lateinit var randomSongsButton: View
private lateinit var songsStarredButton: View
private lateinit var albumsTitle: View
private lateinit var albumsNewestButton: View
private lateinit var albumsRandomButton: View
private lateinit var albumsHighestButton: View
private lateinit var albumsStarredButton: View
private lateinit var albumsRecentButton: View
private lateinit var albumsFrequentButton: View
private lateinit var albumsAlphaByNameButton: View
private lateinit var albumsAlphaByArtistButton: View
private lateinit var videosButton: View
private lateinit var list: LinearLayout
private lateinit var musicTitle: TextView
private lateinit var artistsButton: TextView
private lateinit var albumsButton: TextView
private lateinit var genresButton: TextView
private lateinit var videosTitle: TextView
private lateinit var songsTitle: TextView
private lateinit var randomSongsButton: TextView
private lateinit var songsStarredButton: TextView
private lateinit var albumsTitle: TextView
private lateinit var albumsNewestButton: TextView
private lateinit var albumsRandomButton: TextView
private lateinit var albumsHighestButton: TextView
private lateinit var albumsStarredButton: TextView
private lateinit var albumsRecentButton: TextView
private lateinit var albumsFrequentButton: TextView
private lateinit var albumsAlphaByNameButton: TextView
private lateinit var albumsAlphaByArtistButton: TextView
private lateinit var videosButton: TextView
override fun onCreate(savedInstanceState: Bundle?) {
Util.applyTheme(this.context)
@ -59,8 +58,8 @@ class MainFragment : Fragment(), KoinComponent {
list = view.findViewById(R.id.main_list)
setupButtons()
if (list != null) setupMenuList(list!!)
setupClickListener()
setupItemVisibility()
super.onViewCreated(view, savedInstanceState)
}
@ -71,134 +70,128 @@ class MainFragment : Fragment(), KoinComponent {
val currentId3Setting = Settings.shouldUseId3Tags
// If setting has changed...
if (currentId3Setting != shouldUseId3) {
shouldUseId3 = currentId3Setting
if (currentId3Setting != cachedId3Setting) {
cachedId3Setting = currentId3Setting
shouldRestart = true
}
// then setup the list anew.
if (shouldRestart) {
if (list != null) setupMenuList(list!!)
setupItemVisibility()
}
}
private fun setupButtons() {
val buttons = layoutInflater.inflate(R.layout.main_buttons, list, false)
musicTitle = buttons.findViewById(R.id.main_music)
artistsButton = buttons.findViewById(R.id.main_artists_button)
albumsButton = buttons.findViewById(R.id.main_albums_button)
genresButton = buttons.findViewById(R.id.main_genres_button)
videosTitle = buttons.findViewById(R.id.main_videos_title)
songsTitle = buttons.findViewById(R.id.main_songs)
randomSongsButton = buttons.findViewById(R.id.main_songs_button)
songsStarredButton = buttons.findViewById(R.id.main_songs_starred)
albumsTitle = buttons.findViewById(R.id.main_albums)
albumsNewestButton = buttons.findViewById(R.id.main_albums_newest)
albumsRandomButton = buttons.findViewById(R.id.main_albums_random)
albumsHighestButton = buttons.findViewById(R.id.main_albums_highest)
albumsStarredButton = buttons.findViewById(R.id.main_albums_starred)
albumsRecentButton = buttons.findViewById(R.id.main_albums_recent)
albumsFrequentButton = buttons.findViewById(R.id.main_albums_frequent)
albumsAlphaByNameButton = buttons.findViewById(R.id.main_albums_alphaByName)
albumsAlphaByArtistButton = buttons.findViewById(R.id.main_albums_alphaByArtist)
videosButton = buttons.findViewById(R.id.main_videos)
musicTitle = list.findViewById(R.id.main_music)
artistsButton = list.findViewById(R.id.main_artists_button)
albumsButton = list.findViewById(R.id.main_albums_button)
genresButton = list.findViewById(R.id.main_genres_button)
videosTitle = list.findViewById(R.id.main_videos_title)
songsTitle = list.findViewById(R.id.main_songs)
randomSongsButton = list.findViewById(R.id.main_songs_button)
songsStarredButton = list.findViewById(R.id.main_songs_starred)
albumsTitle = list.findViewById(R.id.main_albums)
albumsNewestButton = list.findViewById(R.id.main_albums_newest)
albumsRandomButton = list.findViewById(R.id.main_albums_random)
albumsHighestButton = list.findViewById(R.id.main_albums_highest)
albumsStarredButton = list.findViewById(R.id.main_albums_starred)
albumsRecentButton = list.findViewById(R.id.main_albums_recent)
albumsFrequentButton = list.findViewById(R.id.main_albums_frequent)
albumsAlphaByNameButton = list.findViewById(R.id.main_albums_alphaByName)
albumsAlphaByArtistButton = list.findViewById(R.id.main_albums_alphaByArtist)
videosButton = list.findViewById(R.id.main_videos)
}
private fun setupMenuList(list: ListView) {
private fun setupItemVisibility() {
// Cache some values
cachedId3Setting = Settings.shouldUseId3Tags
val isOnline = !isOffline()
// TODO: Should use RecyclerView
val adapter = MergeAdapter()
// Music
musicTitle.isVisible = true
artistsButton.isVisible = true
albumsButton.isVisible = isOnline
genresButton.isVisible = true
shouldUseId3 = Settings.shouldUseId3Tags
// Songs
songsTitle.isVisible = isOnline
randomSongsButton.isVisible = true
songsStarredButton.isVisible = isOnline
if (!isOffline()) {
adapter.addView(musicTitle, false)
adapter.addViews(listOf(artistsButton, albumsButton, genresButton), true)
adapter.addView(songsTitle, false)
adapter.addViews(listOf(randomSongsButton, songsStarredButton), true)
adapter.addView(albumsTitle, false)
adapter.addViews(
listOf(
albumsNewestButton,
albumsRecentButton,
albumsFrequentButton
),
true
)
if (!shouldUseId3) {
adapter.addView(albumsHighestButton, true)
}
adapter.addViews(
listOf(
albumsRandomButton,
albumsStarredButton,
albumsAlphaByNameButton,
albumsAlphaByArtistButton
),
true
)
adapter.addView(videosTitle, false)
adapter.addViews(listOf(videosButton), true)
} else {
// Offline supported calls
adapter.addView(musicTitle, false)
adapter.addViews(listOf(artistsButton, genresButton), true)
adapter.addView(songsTitle, false)
adapter.addView(randomSongsButton, true)
}
// Albums
albumsTitle.isVisible = isOnline
albumsNewestButton.isVisible = isOnline
albumsRecentButton.isVisible = isOnline
albumsFrequentButton.isVisible = isOnline
albumsHighestButton.isVisible = isOnline && !cachedId3Setting
albumsRandomButton.isVisible = isOnline
albumsStarredButton.isVisible = isOnline
albumsAlphaByNameButton.isVisible = isOnline
albumsAlphaByArtistButton.isVisible = isOnline
list.adapter = adapter
list.onItemClickListener = listListener
// Videos
videosTitle.isVisible = isOnline
videosButton.isVisible = isOnline
}
private val listListener =
OnItemClickListener { _: AdapterView<*>?, view: View, _: Int, _: Long ->
when {
view === albumsNewestButton -> {
showAlbumList("newest", R.string.main_albums_newest)
}
view === albumsRandomButton -> {
showAlbumList("random", R.string.main_albums_random)
}
view === albumsHighestButton -> {
showAlbumList("highest", R.string.main_albums_highest)
}
view === albumsRecentButton -> {
showAlbumList("recent", R.string.main_albums_recent)
}
view === albumsFrequentButton -> {
showAlbumList("frequent", R.string.main_albums_frequent)
}
view === albumsStarredButton -> {
showAlbumList(Constants.STARRED, R.string.main_albums_starred)
}
view === albumsAlphaByNameButton -> {
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_alphaByName)
}
view === albumsAlphaByArtistButton -> {
showAlbumList("alphabeticalByArtist", R.string.main_albums_alphaByArtist)
}
view === songsStarredButton -> {
showStarredSongs()
}
view === artistsButton -> {
showArtists()
}
view === albumsButton -> {
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_title)
}
view === randomSongsButton -> {
showRandomSongs()
}
view === genresButton -> {
showGenres()
}
view === videosButton -> {
showVideos()
}
}
private fun setupClickListener() {
albumsNewestButton.setOnClickListener {
showAlbumList("newest", R.string.main_albums_newest)
}
albumsRandomButton.setOnClickListener {
showAlbumList("random", R.string.main_albums_random)
}
albumsHighestButton.setOnClickListener {
showAlbumList("highest", R.string.main_albums_highest)
}
albumsRecentButton.setOnClickListener {
showAlbumList("recent", R.string.main_albums_recent)
}
albumsFrequentButton.setOnClickListener {
showAlbumList("frequent", R.string.main_albums_frequent)
}
albumsStarredButton.setOnClickListener {
showAlbumList(Constants.STARRED, R.string.main_albums_starred)
}
albumsAlphaByNameButton.setOnClickListener {
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_alphaByName)
}
albumsAlphaByArtistButton.setOnClickListener {
showAlbumList("alphabeticalByArtist", R.string.main_albums_alphaByArtist)
}
songsStarredButton.setOnClickListener {
showStarredSongs()
}
artistsButton.setOnClickListener {
showArtists()
}
albumsButton.setOnClickListener {
showAlbumList(Constants.ALPHABETICAL_BY_NAME, R.string.main_albums_title)
}
randomSongsButton.setOnClickListener {
showRandomSongs()
}
genresButton.setOnClickListener {
showGenres()
}
videosButton.setOnClickListener {
showVideos()
}
}
private fun showStarredSongs() {
val bundle = Bundle()
bundle.putInt(Constants.INTENT_STARRED, 1)
@ -242,6 +235,6 @@ class MainFragment : Fragment(), KoinComponent {
}
companion object {
private var shouldUseId3 = false
private var cachedId3Setting = false
}
}

View File

@ -1,18 +1,211 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:id="@+id/main_list"
a:layout_width="fill_parent"
a:layout_height="fill_parent"
a:orientation="vertical" >
a:orientation="vertical">
<ListView
a:id="@+id/main_list"
<TextView
a:id="@+id/main_music"
a:layout_width="fill_parent"
a:layout_height="0dp"
a:layout_weight="1" />
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:paddingStart="6dp"
a:text="@string/main.music"
a:textAllCaps="true"
a:textAppearance="?android:attr/textAppearanceSmall"
a:textColor="@color/cyan"
a:textStyle="bold" />
<View
a:id="@+id/main_dummy"
a:layout_width="0dp"
a:layout_height="0dp" />
<TextView
a:id="@+id/main_artists_button"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.artists_title"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_button"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_title"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_genres_button"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.genres_title"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_songs"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:paddingStart="6dp"
a:text="@string/main.songs_title"
a:textAllCaps="true"
a:textAppearance="?android:attr/textAppearanceSmall"
a:textColor="@color/cyan"
a:textStyle="bold" />
<TextView
a:id="@+id/main_songs_button"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.songs_random"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_songs_starred"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.songs_starred"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:paddingStart="6dp"
a:text="@string/main.albums_title"
a:textAllCaps="true"
a:textAppearance="?android:attr/textAppearanceSmall"
a:textColor="@color/cyan"
a:textStyle="bold" />
<TextView
a:id="@+id/main_albums_newest"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_newest"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_recent"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_recent"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_frequent"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_frequent"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_highest"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_highest"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_random"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_random"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_starred"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_starred"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_alphaByName"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_alphaByName"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_albums_alphaByArtist"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.albums_alphaByArtist"
a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
a:id="@+id/main_videos_title"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:paddingStart="6dp"
a:text="@string/main.videos"
a:textAllCaps="true"
a:textAppearance="?android:attr/textAppearanceSmall"
a:textColor="@color/cyan"
a:textStyle="bold" />
<TextView
a:id="@+id/main_videos"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:gravity="center_vertical"
a:minHeight="40dip"
a:paddingStart="6dip"
a:paddingEnd="6dip"
a:text="@string/main.videos"
a:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>

View File

@ -1,100 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
a:orientation="vertical" a:layout_width="fill_parent" a:layout_height="fill_parent">
<TextView a:id="@+id/main_music" a:text="@string/main.music"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
a:textStyle="bold" />
<TextView a:id="@+id/main_artists_button" a:text="@string/main.artists_title"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_albums_button" a:text="@string/main.albums_title"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_genres_button" a:text="@string/main.genres_title"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_songs" a:text="@string/main.songs_title"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
a:textStyle="bold" />
<TextView a:id="@+id/main_songs_button" a:text="@string/main.songs_random"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_songs_starred" a:text="@string/main.songs_starred"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_albums" a:text="@string/main.albums_title"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
a:textStyle="bold" />
<TextView a:id="@+id/main_albums_newest" a:text="@string/main.albums_newest"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_albums_recent" a:text="@string/main.albums_recent"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_albums_frequent" a:text="@string/main.albums_frequent"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_albums_highest" a:text="@string/main.albums_highest"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_albums_random" a:text="@string/main.albums_random"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceMedium" a:gravity="center_vertical"
a:paddingStart="6dip" a:paddingEnd="6dip" a:minHeight="40dip" />
<TextView a:id="@+id/main_albums_starred" a:layout_width="fill_parent"
a:layout_height="wrap_content" a:gravity="center_vertical"
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
a:text="@string/main.albums_starred" a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView a:id="@+id/main_albums_alphaByName" a:layout_width="fill_parent"
a:layout_height="wrap_content" a:gravity="center_vertical"
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
a:text="@string/main.albums_alphaByName" a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView a:id="@+id/main_albums_alphaByArtist" a:layout_width="fill_parent"
a:layout_height="wrap_content" a:gravity="center_vertical"
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
a:text="@string/main.albums_alphaByArtist" a:textAppearance="?android:attr/textAppearanceMedium" />
<TextView a:id="@+id/main_videos_title" a:text="@string/main.videos"
a:layout_width="fill_parent" a:layout_height="wrap_content"
a:textAppearance="?android:attr/textAppearanceSmall" a:textColor="@color/cyan"
a:gravity="center_vertical" a:paddingStart="6dp" a:textAllCaps="true"
a:textStyle="bold" />
<TextView a:id="@+id/main_videos" a:layout_width="fill_parent"
a:layout_height="wrap_content" a:gravity="center_vertical"
a:minHeight="40dip" a:paddingStart="6dip" a:paddingEnd="6dip"
a:text="@string/main.videos" a:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>