Private
Public Access
- New setting "Text and button size" (Normal / Large / Extra large): scales text, icons and buttons on top of the phone's density (App.UI_SCALES) - Larger default text, rows, tiles, touch targets and player icons; all sizes now live in res/values/dimens.xml - Seek bar knob drawn in code, since Android 2.x caches XML shapes at the size they were first loaded - Full-width buttons wrap to two lines instead of cutting words off - Shorter labels so they fit 240x320 screens in both languages - tools/check_fit.py checks that UI texts fit their slots at every size and language using Droid Sans metrics; build.sh runs it and setup_toolchain.sh fetches the font Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
154 lines
5.6 KiB
Java
154 lines
5.6 KiB
Java
package com.minamp;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import android.content.Context;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.BaseAdapter;
|
|
import android.widget.ImageView;
|
|
import android.widget.TextView;
|
|
|
|
import com.minamp.plex.Item;
|
|
|
|
/** Rows for artists / albums / tracks / playlists, with section headers and paging. */
|
|
public class ItemAdapter extends BaseAdapter {
|
|
|
|
public static final int MODE_DEFAULT = 0, MODE_ALBUM_TRACKS = 1, MODE_QUEUE = 2;
|
|
|
|
public interface Pager { void loadMore(int from); }
|
|
|
|
private final Context ctx;
|
|
private final LayoutInflater inflater;
|
|
private final List<Item> items = new ArrayList<Item>();
|
|
private final int mode;
|
|
private final int artPx;
|
|
private final int accent, text;
|
|
private int total = -1; // total available on the server, -1 = everything loaded
|
|
private boolean loadingMore;
|
|
private Pager pager;
|
|
private String albumArtist = "";
|
|
private int highlight = -1; // queue index highlight
|
|
private final App app;
|
|
|
|
public ItemAdapter(Context c, int mode) {
|
|
ctx = c;
|
|
this.mode = mode;
|
|
inflater = LayoutInflater.from(c);
|
|
artPx = Ui.dimen(c, R.dimen.row_art);
|
|
accent = c.getResources().getColor(R.color.accent);
|
|
text = c.getResources().getColor(R.color.text);
|
|
app = App.get();
|
|
}
|
|
|
|
public void setPager(Pager p) { pager = p; }
|
|
public void setAlbumArtist(String a) { albumArtist = a == null ? "" : a; }
|
|
public void setHighlight(int i) { highlight = i; notifyDataSetChanged(); }
|
|
|
|
public void set(List<Item> list, int totalSize) {
|
|
items.clear();
|
|
items.addAll(list);
|
|
total = totalSize;
|
|
loadingMore = false;
|
|
notifyDataSetChanged();
|
|
}
|
|
|
|
public void append(List<Item> list, int totalSize) {
|
|
items.addAll(list);
|
|
total = totalSize;
|
|
loadingMore = false;
|
|
notifyDataSetChanged();
|
|
}
|
|
|
|
public void loadFailed() { loadingMore = false; }
|
|
|
|
public List<Item> items() { return items; }
|
|
|
|
/** Only the tracks, and the index of position within them (for "play from here"). */
|
|
public List<Item> tracks() {
|
|
List<Item> t = new ArrayList<Item>();
|
|
for (int i = 0; i < items.size(); i++) if (items.get(i).type == Item.TRACK) t.add(items.get(i));
|
|
return t;
|
|
}
|
|
|
|
public int trackIndex(int position) {
|
|
int n = 0;
|
|
for (int i = 0; i < position && i < items.size(); i++) if (items.get(i).type == Item.TRACK) n++;
|
|
return n;
|
|
}
|
|
|
|
@Override public int getCount() { return items.size(); }
|
|
@Override public Item getItem(int i) { return items.get(i); }
|
|
@Override public long getItemId(int i) { return i; }
|
|
@Override public int getViewTypeCount() { return 2; }
|
|
@Override public int getItemViewType(int i) { return items.get(i).type == Item.HEADER ? 1 : 0; }
|
|
@Override public boolean areAllItemsEnabled() { return false; }
|
|
@Override public boolean isEnabled(int i) { return items.get(i).type != Item.HEADER; }
|
|
|
|
private static final class Holder {
|
|
ImageView art; TextView num, title, sub, right;
|
|
}
|
|
|
|
@Override
|
|
public View getView(int pos, View v, ViewGroup parent) {
|
|
if (pager != null && !loadingMore && total > items.size() && pos >= items.size() - 15) {
|
|
loadingMore = true;
|
|
final int from = items.size();
|
|
app.handler.post(new Runnable() { public void run() { pager.loadMore(from); } });
|
|
}
|
|
Item it = items.get(pos);
|
|
if (it.type == Item.HEADER) {
|
|
if (v == null) v = inflater.inflate(R.layout.row_header, parent, false);
|
|
((TextView) v).setText(it.title.toUpperCase());
|
|
return v;
|
|
}
|
|
Holder h;
|
|
if (v == null) {
|
|
v = inflater.inflate(R.layout.row_item, parent, false);
|
|
h = new Holder();
|
|
h.art = (ImageView) v.findViewById(R.id.row_art);
|
|
h.num = (TextView) v.findViewById(R.id.row_num);
|
|
h.title = (TextView) v.findViewById(R.id.row_title);
|
|
h.sub = (TextView) v.findViewById(R.id.row_sub);
|
|
h.right = (TextView) v.findViewById(R.id.row_right);
|
|
v.setTag(h);
|
|
} else {
|
|
h = (Holder) v.getTag();
|
|
}
|
|
|
|
h.title.setText(it.title);
|
|
boolean numbered = mode == MODE_ALBUM_TRACKS && it.type == Item.TRACK;
|
|
if (numbered) {
|
|
h.art.setVisibility(View.GONE);
|
|
h.art.setTag(R.id.tag_image, null);
|
|
h.num.setVisibility(View.VISIBLE);
|
|
h.num.setText(it.index > 0 ? String.valueOf(it.index) : "•");
|
|
boolean showArtist = it.artist.length() > 0 && !it.artist.equals(albumArtist);
|
|
h.sub.setVisibility(showArtist ? View.VISIBLE : View.GONE);
|
|
h.sub.setText(it.artist);
|
|
} else {
|
|
h.art.setVisibility(View.VISIBLE);
|
|
h.num.setVisibility(View.GONE);
|
|
app.images.load(h.art, it.thumb, artPx, R.drawable.art_placeholder);
|
|
String sub = it.subtitle();
|
|
h.sub.setVisibility(sub.length() > 0 ? View.VISIBLE : View.GONE);
|
|
h.sub.setText(sub);
|
|
}
|
|
|
|
String right = "";
|
|
if (it.type == Item.TRACK && it.duration > 0) right = Ui.time(it.duration);
|
|
h.right.setText(right);
|
|
|
|
boolean current;
|
|
if (mode == MODE_QUEUE) current = pos == highlight;
|
|
else {
|
|
Item playing = PlayQueue.get().current();
|
|
current = playing != null && it.type == Item.TRACK && playing.ratingKey.equals(it.ratingKey);
|
|
}
|
|
h.title.setTextColor(current ? accent : text);
|
|
return v;
|
|
}
|
|
}
|