mirror of
https://codeberg.org/Bazsalanszky/Infinity-For-Lemmy.git
synced 2025-01-30 11:34:43 +01:00
Show live comments in RPAN broadcasts.
This commit is contained in:
parent
4204ce4773
commit
372f373601
@ -177,6 +177,8 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'androidx.palette:palette:1.0.0'
|
implementation 'androidx.palette:palette:1.0.0'
|
||||||
|
|
||||||
|
implementation 'com.tinder.scarlet:scarlet:0.1.12'
|
||||||
|
|
||||||
|
|
||||||
/**** Builds and flavors ****/
|
/**** Builds and flavors ****/
|
||||||
// debugImplementation because LeakCanary should only run in debug builds.
|
// debugImplementation because LeakCanary should only run in debug builds.
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package ml.docilealligator.infinityforreddit;
|
||||||
|
|
||||||
|
public class RPANComment {
|
||||||
|
public String author;
|
||||||
|
public String authorIconImage;
|
||||||
|
public String content;
|
||||||
|
public long createdUTC;
|
||||||
|
|
||||||
|
public RPANComment(String author, String authorIconImage, String content, long createdUTC) {
|
||||||
|
this.author = author;
|
||||||
|
this.authorIconImage = authorIconImage;
|
||||||
|
this.content = content;
|
||||||
|
this.createdUTC = createdUTC;
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@ import androidx.appcompat.app.AppCompatActivity;
|
|||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@ -217,7 +219,25 @@ public class RPANActivity extends AppCompatActivity {
|
|||||||
sectionsPagerAdapter = new SectionsPagerAdapter(this);
|
sectionsPagerAdapter = new SectionsPagerAdapter(this);
|
||||||
viewPager2.setAdapter(sectionsPagerAdapter);
|
viewPager2.setAdapter(sectionsPagerAdapter);
|
||||||
viewPager2.setOffscreenPageLimit(3);
|
viewPager2.setOffscreenPageLimit(3);
|
||||||
//fixViewPager2Sensitivity(viewPager2);
|
fixViewPager2Sensitivity(viewPager2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fixViewPager2Sensitivity(ViewPager2 viewPager2) {
|
||||||
|
try {
|
||||||
|
Field recyclerViewField = ViewPager2.class.getDeclaredField("mRecyclerView");
|
||||||
|
recyclerViewField.setAccessible(true);
|
||||||
|
|
||||||
|
RecyclerView recyclerView = (RecyclerView) recyclerViewField.get(viewPager2);
|
||||||
|
|
||||||
|
Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop");
|
||||||
|
touchSlopField.setAccessible(true);
|
||||||
|
|
||||||
|
Object touchSlopBox = touchSlopField.get(recyclerView);
|
||||||
|
if (touchSlopBox != null) {
|
||||||
|
int touchSlop = (int) touchSlopBox;
|
||||||
|
touchSlopField.set(recyclerView, touchSlop * 4);
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException ignore) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SectionsPagerAdapter extends FragmentStateAdapter {
|
private class SectionsPagerAdapter extends FragmentStateAdapter {
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package ml.docilealligator.infinityforreddit.adapters;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.RequestManager;
|
||||||
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
|
||||||
|
import ml.docilealligator.infinityforreddit.R;
|
||||||
|
import ml.docilealligator.infinityforreddit.RPANComment;
|
||||||
|
|
||||||
|
public class RPANCommentStreamRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
private RequestManager glide;
|
||||||
|
private ArrayList<RPANComment> rpanComments;
|
||||||
|
|
||||||
|
public RPANCommentStreamRecyclerViewAdapter(Context context) {
|
||||||
|
glide = Glide.with(context);
|
||||||
|
rpanComments = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
return new RPANCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(
|
||||||
|
R.layout.item_rpan_comment, parent, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||||
|
if (holder instanceof RPANCommentViewHolder) {
|
||||||
|
((RPANCommentViewHolder) holder).authorTextView.setText(rpanComments.get(position).author);
|
||||||
|
((RPANCommentViewHolder) holder).contentTextView.setText(rpanComments.get(position).content);
|
||||||
|
glide.load(rpanComments.get(position).authorIconImage)
|
||||||
|
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))
|
||||||
|
.error(glide.load(R.drawable.subreddit_default_icon)
|
||||||
|
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))))
|
||||||
|
.into(((RPANCommentViewHolder) holder).iconImageView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return rpanComments == null ? 0 : rpanComments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
|
||||||
|
super.onViewRecycled(holder);
|
||||||
|
if (holder instanceof RPANCommentViewHolder) {
|
||||||
|
glide.clear(((RPANCommentViewHolder) holder).iconImageView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRPANComment(RPANComment rpanComment) {
|
||||||
|
rpanComments.add(rpanComment);
|
||||||
|
notifyItemInserted(rpanComments.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RPANCommentViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
ImageView iconImageView;
|
||||||
|
TextView authorTextView;
|
||||||
|
TextView timeTextView;
|
||||||
|
TextView contentTextView;
|
||||||
|
|
||||||
|
public RPANCommentViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
iconImageView = itemView.findViewById(R.id.icon_image_view_item_rpan_comment);
|
||||||
|
authorTextView = itemView.findViewById(R.id.author_text_view_item_rpan_comment);
|
||||||
|
contentTextView = itemView.findViewById(R.id.content_text_view_item_rpan_comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,11 @@ package ml.docilealligator.infinityforreddit.fragments;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -11,7 +14,9 @@ import android.widget.ImageButton;
|
|||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||||
@ -28,9 +33,14 @@ import com.google.android.exoplayer2.ui.PlayerView;
|
|||||||
import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder;
|
import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
@ -39,19 +49,30 @@ import butterknife.ButterKnife;
|
|||||||
import ml.docilealligator.infinityforreddit.Infinity;
|
import ml.docilealligator.infinityforreddit.Infinity;
|
||||||
import ml.docilealligator.infinityforreddit.R;
|
import ml.docilealligator.infinityforreddit.R;
|
||||||
import ml.docilealligator.infinityforreddit.RPANBroadcast;
|
import ml.docilealligator.infinityforreddit.RPANBroadcast;
|
||||||
|
import ml.docilealligator.infinityforreddit.RPANComment;
|
||||||
|
import ml.docilealligator.infinityforreddit.adapters.RPANCommentStreamRecyclerViewAdapter;
|
||||||
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
|
import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper;
|
||||||
|
import ml.docilealligator.infinityforreddit.utils.JSONUtils;
|
||||||
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
|
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.WebSocket;
|
||||||
|
import okhttp3.WebSocketListener;
|
||||||
|
|
||||||
public class ViewRPANBroadcastFragment extends Fragment {
|
public class ViewRPANBroadcastFragment extends Fragment {
|
||||||
|
|
||||||
public static final String EXTRA_RPAN_BROADCAST = "ERB";
|
public static final String EXTRA_RPAN_BROADCAST = "ERB";
|
||||||
private static final String IS_MUTE_STATE = "IMS";
|
private static final String IS_MUTE_STATE = "IMS";
|
||||||
|
|
||||||
|
@BindView(R.id.constraint_layout_exo_rpan_broadcast_playback_control_view)
|
||||||
|
ConstraintLayout constraintLayout;
|
||||||
@BindView(R.id.player_view_view_rpan_broadcast_fragment)
|
@BindView(R.id.player_view_view_rpan_broadcast_fragment)
|
||||||
PlayerView playerView;
|
PlayerView playerView;
|
||||||
@BindView(R.id.mute_exo_playback_control_view)
|
@BindView(R.id.recycler_view_exo_rpan_broadcast_playback_control_view)
|
||||||
|
RecyclerView recyclerView;
|
||||||
|
@BindView(R.id.mute_exo_rpan_broadcast_playback_control_view)
|
||||||
ImageButton muteButton;
|
ImageButton muteButton;
|
||||||
@BindView(R.id.hd_exo_playback_control_view)
|
@BindView(R.id.hd_exo_rpan_broadcast_playback_control_view)
|
||||||
ImageButton hdButton;
|
ImageButton hdButton;
|
||||||
@Inject
|
@Inject
|
||||||
@Named("default")
|
@Named("default")
|
||||||
@ -62,12 +83,14 @@ public class ViewRPANBroadcastFragment extends Fragment {
|
|||||||
@Inject
|
@Inject
|
||||||
CustomThemeWrapper mCustomThemeWrapper;
|
CustomThemeWrapper mCustomThemeWrapper;
|
||||||
@Inject
|
@Inject
|
||||||
SimpleCache mSimpleCache;
|
Executor mExecutor;
|
||||||
private AppCompatActivity mActivity;
|
private AppCompatActivity mActivity;
|
||||||
private RPANBroadcast rpanBroadcast;
|
private RPANBroadcast rpanBroadcast;
|
||||||
private SimpleExoPlayer player;
|
private SimpleExoPlayer player;
|
||||||
private DefaultTrackSelector trackSelector;
|
private DefaultTrackSelector trackSelector;
|
||||||
private DataSource.Factory dataSourceFactory;
|
private DataSource.Factory dataSourceFactory;
|
||||||
|
private Handler handler;
|
||||||
|
private RPANCommentStreamRecyclerViewAdapter adapter;
|
||||||
|
|
||||||
private boolean wasPlaying;
|
private boolean wasPlaying;
|
||||||
private boolean isMute = false;
|
private boolean isMute = false;
|
||||||
@ -90,6 +113,20 @@ public class ViewRPANBroadcastFragment extends Fragment {
|
|||||||
|
|
||||||
rpanBroadcast = getArguments().getParcelable(EXTRA_RPAN_BROADCAST);
|
rpanBroadcast = getArguments().getParcelable(EXTRA_RPAN_BROADCAST);
|
||||||
|
|
||||||
|
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) {
|
||||||
|
//Set player controller bottom margin in order to display it above the navbar
|
||||||
|
int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
|
||||||
|
//LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view);
|
||||||
|
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) constraintLayout.getLayoutParams();
|
||||||
|
params.bottomMargin = getResources().getDimensionPixelSize(resourceId);
|
||||||
|
} else {
|
||||||
|
//Set player controller right margin in order to display it above the navbar
|
||||||
|
int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
|
||||||
|
//LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view);
|
||||||
|
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) constraintLayout.getLayoutParams();
|
||||||
|
params.rightMargin = getResources().getDimensionPixelSize(resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
playerView.setControllerVisibilityListener(visibility -> {
|
playerView.setControllerVisibilityListener(visibility -> {
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
case View.GONE:
|
case View.GONE:
|
||||||
@ -186,6 +223,21 @@ public class ViewRPANBroadcastFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
adapter = new RPANCommentStreamRecyclerViewAdapter(mActivity);
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
|
||||||
|
handler = new Handler();
|
||||||
|
|
||||||
|
Request request = new Request.Builder().url(rpanBroadcast.rpanPost.liveCommentsWebsocketUrl).build();
|
||||||
|
CommentStreamWebSocketListener listener = new CommentStreamWebSocketListener(this::parseComment);
|
||||||
|
OkHttpClient okHttpClient = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
WebSocket webSocket = okHttpClient.newWebSocket(request, listener);
|
||||||
|
okHttpClient.dispatcher().executorService().shutdown();
|
||||||
|
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +255,26 @@ public class ViewRPANBroadcastFragment extends Fragment {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void parseComment(String commentJson) {
|
||||||
|
mExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
JSONObject commentObject = new JSONObject(commentJson);
|
||||||
|
if (commentObject.getString(JSONUtils.TYPE_KEY).equals("new_comment")) {
|
||||||
|
JSONObject payload = commentObject.getJSONObject(JSONUtils.PAYLOAD_KEY);
|
||||||
|
RPANComment rpanComment = new RPANComment(
|
||||||
|
payload.getString(JSONUtils.AUTHOR_KEY),
|
||||||
|
payload.getString(JSONUtils.AUTHOR_ICON_IMAGE),
|
||||||
|
payload.getString(JSONUtils.BODY_KEY),
|
||||||
|
payload.getLong(JSONUtils.CREATED_UTC_KEY));
|
||||||
|
|
||||||
|
handler.post(() -> adapter.addRPANComment(rpanComment));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
@ -237,4 +309,22 @@ public class ViewRPANBroadcastFragment extends Fragment {
|
|||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
mActivity = (AppCompatActivity) context;
|
mActivity = (AppCompatActivity) context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class CommentStreamWebSocketListener extends WebSocketListener {
|
||||||
|
MessageReceivedListener messageReceivedListener;
|
||||||
|
|
||||||
|
CommentStreamWebSocketListener(MessageReceivedListener messageReceivedListener) {
|
||||||
|
this.messageReceivedListener = messageReceivedListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(@NonNull WebSocket webSocket, @NonNull String text) {
|
||||||
|
Log.i("asfasdf", "s " + text);
|
||||||
|
messageReceivedListener.onMessage(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MessageReceivedListener {
|
||||||
|
void onMessage(String text);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -162,4 +162,6 @@ public class JSONUtils {
|
|||||||
public static final String CHAT_DISABLED_KEY = "chat_disabled";
|
public static final String CHAT_DISABLED_KEY = "chat_disabled";
|
||||||
public static final String BROADCAST_TIME_KEY = "broadcast_time";
|
public static final String BROADCAST_TIME_KEY = "broadcast_time";
|
||||||
public static final String ESTIMATED_REMAINING_TIME_KEY = "estimated_remaining_time";
|
public static final String ESTIMATED_REMAINING_TIME_KEY = "estimated_remaining_time";
|
||||||
|
public static final String PAYLOAD_KEY = "payload";
|
||||||
|
public static final String AUTHOR_ICON_IMAGE = "author_icon_img";
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,102 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#44000000"
|
||||||
|
android:id="@+id/constraint_layout_exo_rpan_broadcast_playback_control_view"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/control_linear_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingTop="4dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/hd_exo_rpan_broadcast_playback_control_view"
|
||||||
|
android:src="@drawable/ic_video_quality_24dp"
|
||||||
|
style="@style/ExoMediaButton"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<ImageButton android:id="@id/exo_rew"
|
||||||
|
style="@style/ExoMediaButton.Rewind" />
|
||||||
|
|
||||||
|
<ImageButton android:id="@id/exo_play"
|
||||||
|
style="@style/ExoMediaButton.Play"/>
|
||||||
|
|
||||||
|
<ImageButton android:id="@id/exo_pause"
|
||||||
|
style="@style/ExoMediaButton.Pause" />
|
||||||
|
|
||||||
|
<ImageButton android:id="@id/exo_ffwd"
|
||||||
|
style="@style/ExoMediaButton.FastForward" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/mute_exo_rpan_broadcast_playback_control_view"
|
||||||
|
style="@style/ExoMediaButton"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view_exo_rpan_broadcast_playback_control_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:paddingTop="16dp"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/control_linear_layout"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/time_bar_linear_layout"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/time_bar_linear_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<TextView android:id="@id/exo_position"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="4dp"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:fontFamily="?attr/font_family" />
|
||||||
|
|
||||||
|
<com.google.android.exoplayer2.ui.DefaultTimeBar
|
||||||
|
android:id="@id/exo_progress"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
app:bar_height="2dp"
|
||||||
|
app:scrubber_color="@color/colorAccent"
|
||||||
|
app:played_color="@color/colorAccent" />
|
||||||
|
|
||||||
|
<TextView android:id="@id/exo_duration"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:fontFamily="?attr/font_family" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -10,6 +10,6 @@
|
|||||||
android:id="@+id/player_view_view_rpan_broadcast_fragment"
|
android:id="@+id/player_view_view_rpan_broadcast_fragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:controller_layout_id="@layout/exo_playback_control_view" />
|
app:controller_layout_id="@layout/exo_rpan_broadcast_playback_control_view" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
38
app/src/main/res/layout/item_rpan_comment.xml
Normal file
38
app/src/main/res/layout/item_rpan_comment.xml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon_image_view_item_rpan_comment"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="center_vertical" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="0dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/author_text_view_item_rpan_comment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/colorPrimary" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/content_text_view_item_rpan_comment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textColor="#FFFFFF" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user