Add Android TV Edition support
- Update AndroidManifest.xml for TV compatibility - Add ChannelAdapter with D-pad navigation support - Update MainActivity for TV UI optimization - Add Android TV specific resources: - banner_streamplayer.xml for TV launcher - bg_channel_item_selector for focus states - values-sw720dp for large screens - integers.xml for TV configurations - Update item_channel.xml for TV navigation - Remove unused mobile-specific drawable Features: - Android TV Leanback support - D-pad navigation optimization - TV-optimized layouts and focus management - Large screen resources for TV displays 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
android:banner="@drawable/banner_streamplayer"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
@@ -27,9 +28,17 @@
|
|||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.software.leanback"
|
||||||
|
android:required="false" />
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.touchscreen"
|
||||||
|
android:required="false" />
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ public class ChannelAdapter extends RecyclerView.Adapter<ChannelAdapter.ChannelV
|
|||||||
listener.onChannelClick(channel);
|
listener.onChannelClick(channel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
holder.itemView.setOnFocusChangeListener((v, hasFocus) -> {
|
||||||
|
float scale = hasFocus ? 1.08f : 1f;
|
||||||
|
v.animate().scaleX(scale).scaleY(scale).setDuration(120).start();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
RecyclerView recyclerView = findViewById(R.id.channel_grid);
|
RecyclerView recyclerView = findViewById(R.id.channel_grid);
|
||||||
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
|
recyclerView.setLayoutManager(new GridLayoutManager(this, getSpanCount()));
|
||||||
|
recyclerView.setHasFixedSize(true);
|
||||||
ChannelAdapter adapter = new ChannelAdapter(
|
ChannelAdapter adapter = new ChannelAdapter(
|
||||||
ChannelRepository.getChannels(),
|
ChannelRepository.getChannels(),
|
||||||
channel -> {
|
channel -> {
|
||||||
@@ -25,5 +26,10 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
});
|
});
|
||||||
recyclerView.setAdapter(adapter);
|
recyclerView.setAdapter(adapter);
|
||||||
|
recyclerView.post(recyclerView::requestFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSpanCount() {
|
||||||
|
return getResources().getInteger(R.integer.channel_grid_span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
app/src/main/res/drawable/banner_streamplayer.xml
Normal file
18
app/src/main/res/drawable/banner_streamplayer.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<gradient
|
||||||
|
android:angle="0"
|
||||||
|
android:endColor="#FF002766"
|
||||||
|
android:startColor="#FF0F4C81" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<bitmap
|
||||||
|
android:antialias="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:src="@mipmap/ic_launcher" />
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
<solid android:color="#33212121" />
|
|
||||||
<corners android:radius="12dp" />
|
|
||||||
<stroke
|
|
||||||
android:width="1dp"
|
|
||||||
android:color="#55FFFFFF" />
|
|
||||||
</shape>
|
|
||||||
30
app/src/main/res/drawable/bg_channel_item_selector.xml
Normal file
30
app/src/main/res/drawable/bg_channel_item_selector.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_focused="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="#66FFFFFF" />
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="2dp"
|
||||||
|
android:color="#FFFFFFFF" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="#55FFFFFF" />
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="2dp"
|
||||||
|
android:color="#FFFFFFFF" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="#33212121" />
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="#55FFFFFF" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
@@ -3,7 +3,9 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="6dp"
|
android:layout_margin="6dp"
|
||||||
android:background="@drawable/bg_channel_item"
|
android:background="@drawable/bg_channel_item_selector"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
|
|||||||
4
app/src/main/res/values-sw720dp/integers.xml
Normal file
4
app/src/main/res/values-sw720dp/integers.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<integer name="channel_grid_span">5</integer>
|
||||||
|
</resources>
|
||||||
4
app/src/main/res/values/integers.xml
Normal file
4
app/src/main/res/values/integers.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<integer name="channel_grid_span">3</integer>
|
||||||
|
</resources>
|
||||||
Reference in New Issue
Block a user