Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Android TV #939

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ android:

before_install:
- yes | sdkmanager "platforms;android-27"
script: ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleDebug lintDebug testDebugUnitTest
script:
- ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleNormalDebug lintNormalDebug testNormalDebugUnitTest
- ./gradlew -Dorg.gradle.jvmargs=-Xmx1536m assembleTvDebug lintTvDebug testTvDebugUnitTest

licenses:
- '.+'
16 changes: 15 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,17 @@ android {
applicationIdSuffix ".beta"
}
}

flavorDimensions "platform"
productFlavors {
normal {
dimension "platform"
}
tv {
dimension "platform"
minSdkVersion 21
versionNameSuffix "-tv"
}
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
Expand Down Expand Up @@ -66,6 +76,10 @@ dependencies {
implementation "com.android.support:recyclerview-v7:$supportLibVersion"
implementation "com.android.support:preference-v14:$supportLibVersion"

tvImplementation "com.android.support:leanback-v17:$supportLibVersion"
tvImplementation 'com.android.support.constraint:constraint-layout:1.0.2'
tvImplementation 'com.github.bumptech.glide:glide:3.8.0'

implementation 'com.google.code.gson:gson:2.8.2'
implementation 'ch.acra:acra:4.9.2'

Expand Down
35 changes: 35 additions & 0 deletions app/src/tv/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.schabi.newpipe">

<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.software.leanback"
android:required="true" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<application>
<activity
android:name=".tv.MainActivity"
android:banner="@drawable/app_icon_your_company"
android:icon="@drawable/app_icon_your_company"
android:label="@string/title_activity_main"
android:logo="@drawable/app_icon_your_company"
android:screenOrientation="landscape"
android:theme="@style/Theme.Leanback">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".tv.DetailsActivity" />
<activity android:name=".tv.PlaybackActivity" />
<activity android:name=".tv.BrowseErrorActivity" />
</application>

</manifest>
62 changes: 62 additions & 0 deletions app/src/tv/java/org/schabi/newpipe/tv/BrowseErrorActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.schabi.newpipe.tv;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;

import org.schabi.newpipe.R;

public class BrowseErrorActivity extends Activity {
private static int TIMER_DELAY = 3000;
private static int SPINNER_WIDTH = 100;
private static int SPINNER_HEIGHT = 100;

private ErrorFragment mErrorFragment;
private SpinnerFragment mSpinnerFragment;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

testError();
}

private void testError() {
mErrorFragment = new ErrorFragment();
getFragmentManager().beginTransaction().add(R.id.main_browse_fragment, mErrorFragment).commit();

mSpinnerFragment = new SpinnerFragment();
getFragmentManager().beginTransaction().add(R.id.main_browse_fragment, mSpinnerFragment).commit();

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
getFragmentManager().beginTransaction().remove(mSpinnerFragment).commit();
mErrorFragment.setErrorContent();
}
}, TIMER_DELAY);
}

static public class SpinnerFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ProgressBar progressBar = new ProgressBar(container.getContext());
if (container instanceof FrameLayout) {
FrameLayout.LayoutParams layoutParams =
new FrameLayout.LayoutParams(SPINNER_WIDTH, SPINNER_HEIGHT, Gravity.CENTER);
progressBar.setLayoutParams(layoutParams);
}
return progressBar;
}
}
}
76 changes: 76 additions & 0 deletions app/src/tv/java/org/schabi/newpipe/tv/CardPresenter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.schabi.newpipe.tv;

import android.graphics.drawable.Drawable;
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.Presenter;
import android.util.Log;
import android.view.ViewGroup;

import com.bumptech.glide.Glide;

import org.schabi.newpipe.R;

public class CardPresenter extends Presenter {
private static final String TAG = "CardPresenter";

private static final int CARD_WIDTH = 313;
private static final int CARD_HEIGHT = 176;
private static int sSelectedBackgroundColor;
private static int sDefaultBackgroundColor;
private Drawable mDefaultCardImage;

private static void updateCardBackgroundColor(ImageCardView view, boolean selected) {
int color = selected ? sSelectedBackgroundColor : sDefaultBackgroundColor;

view.setBackgroundColor(color);
view.findViewById(R.id.info_field).setBackgroundColor(color);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
Log.d(TAG, "onCreateViewHolder");

sDefaultBackgroundColor = parent.getResources().getColor(R.color.default_background);
sSelectedBackgroundColor = parent.getResources().getColor(R.color.selected_background);
mDefaultCardImage = parent.getResources().getDrawable(R.drawable.movie);

ImageCardView cardView = new ImageCardView(parent.getContext()) {
@Override
public void setSelected(boolean selected) {
updateCardBackgroundColor(this, selected);
super.setSelected(selected);
}
};

cardView.setFocusable(true);
cardView.setFocusableInTouchMode(true);
updateCardBackgroundColor(cardView, false);
return new ViewHolder(cardView);
}

@Override
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
Movie movie = (Movie) item;
ImageCardView cardView = (ImageCardView) viewHolder.view;

Log.d(TAG, "onBindViewHolder");
if (movie.getImageUrl() != null) {
cardView.setTitleText(movie.getTitle());
cardView.setContentText(movie.getStudio());
cardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT);
Glide.with(viewHolder.view.getContext())
.load(movie.getImageUrl())
.centerCrop()
.error(mDefaultCardImage)
.into(cardView.getMainImageView());
}
}

@Override
public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
Log.d(TAG, "onUnbindViewHolder");
ImageCardView cardView = (ImageCardView) viewHolder.view;
cardView.setBadgeImage(null);
cardView.setMainImage(null);
}
}
18 changes: 18 additions & 0 deletions app/src/tv/java/org/schabi/newpipe/tv/DetailsActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.schabi.newpipe.tv;

import android.app.Activity;
import android.os.Bundle;

import org.schabi.newpipe.R;

public class DetailsActivity extends Activity {
public static final String SHARED_ELEMENT_NAME = "hero";
public static final String MOVIE = "Movie";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.schabi.newpipe.tv;

import android.support.v17.leanback.widget.AbstractDetailsDescriptionPresenter;

public class DetailsDescriptionPresenter extends AbstractDetailsDescriptionPresenter {

@Override
protected void onBindDescription(ViewHolder viewHolder, Object item) {
Movie movie = (Movie) item;

if (movie != null) {
viewHolder.getTitle().setText(movie.getTitle());
viewHolder.getSubtitle().setText(movie.getStudio());
viewHolder.getBody().setText(movie.getDescription());
}
}
}
33 changes: 33 additions & 0 deletions app/src/tv/java/org/schabi/newpipe/tv/ErrorFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.schabi.newpipe.tv;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import org.schabi.newpipe.R;

public class ErrorFragment extends android.support.v17.leanback.app.ErrorFragment {
private static final String TAG = "ErrorFragment";
private static final boolean TRANSLUCENT = true;

@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setTitle(getString(R.string.app_name));
}

void setErrorContent() {
setImageDrawable(getResources().getDrawable(R.drawable.lb_ic_sad_cloud));
setMessage(getString(R.string.error_fragment_message));
setDefaultBackground(TRANSLUCENT);

setButtonText(getString(R.string.dismiss_error));
setButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
getFragmentManager().beginTransaction().remove(ErrorFragment.this).commit();
}
});
}
}
15 changes: 15 additions & 0 deletions app/src/tv/java/org/schabi/newpipe/tv/MainActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.schabi.newpipe.tv;

import android.app.Activity;
import android.os.Bundle;

import org.schabi.newpipe.R;

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Loading