ZyreoTv mylist

This commit is contained in:
guozhen 2025-04-16 20:23:24 +08:00
parent 956eba20ef
commit 8f079f407b
60 changed files with 1357 additions and 368 deletions

View File

@ -17,31 +17,28 @@ android {
vectorDrawables.useSupportLibrary = true
}
// signingConfigs {
// debug {
// storeFile file('viontv.jks')
// storePassword "android123456"
// keyAlias 'key0'
// keyPassword "android123456"
// v1SigningEnabled true
// v2SigningEnabled true
// }
// release {
// storeFile file('viontv.jks')
// storePassword "android123456"
// keyAlias 'key0'
// keyPassword "android123456"
// v1SigningEnabled true
// v2SigningEnabled true
// }
// }
signingConfigs {
signs {
storeFile file('zyreotv.jks')
storePassword "20250416"
keyAlias 'key0'
keyPassword "20250416"
v1SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.signs
minifyEnabled false
}
}

View File

@ -19,7 +19,7 @@ public class VTApplication extends Application {
public static VTApplication AppContext;
public static boolean isCurrentPage = true;
public static boolean isCurrentPage = false;
public static VTApplication getAppContext() {
return AppContext;

View File

@ -51,8 +51,9 @@ public class VTApi extends VTBaseApi {
//错误重连
builder.retryOnConnectionFailure(true);
builder.addInterceptor(new VTHeaderInterceptor());
builder.addInterceptor(new VTBodyloadInterceptor());
// if(Config.IS_DEBUG) {
// if(Config.IS_DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(message -> {
try {
String text = URLDecoder.decode(message, "utf-8");
@ -64,7 +65,7 @@ public class VTApi extends VTBaseApi {
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
// }
// }
return builder.build();
}

View File

@ -24,7 +24,7 @@ public interface VTApiService {
/**
* 正式测试服
*/
boolean isProduce = false;
boolean isProduce = true;
String URL = isProduce ? "https://api-zyreotv.zyreotv.com/7834f11d/" : "https://test1-api.guyantv.com";
public static final String rankTop10Type = "most_trending";
@ -34,37 +34,37 @@ public interface VTApiService {
/**
* 注册
*
*
* @return
*/
@POST("/customer/register")
@POST("customer/register")
Observable<VTResult<RegisteredBean>> register();
/**
* 首页顶部
*
*
* @return
*/
@POST("/homeTop")
@POST("homeTop")
Observable<VTResult<HomeTopBean>> homeTop();
/**
* 首页9宫格和banner
*
*
* @return
*/
@POST("/homeBannerAndNineSquare")
@POST("homeBannerAndNineSquare")
Observable<VTResult<HomeTopBannerBean>> bannersquare();
/**
* 首页底部列表
*
*
* @return
*/
@FormUrlEncoded
@POST("/newShortPlay")
@POST("newShortPlay")
Observable<VTResult<VTVideoListBean>> newShortPlay(@Field("current_page") int currentpage, @Field("page_size") int pagesize);
@ -74,44 +74,44 @@ public interface VTApiService {
* @return
*/
@FormUrlEncoded
@POST("/homeRanking")
@POST("homeRanking")
Observable<VTResult<VTVideoListBean>> homeTop10(@Field("type") String type);
/**
* 获取视频详情
*
*
* @return
*/
@GET("/getVideoDetails")
@GET("getVideoDetails")
Observable<VTResult<VTVideoDetailsBean>> getVideoDetails(@Query("short_play_id") int short_play_id, @Query("video_id") int video_id);
/**
* 首页TabItem Banner
*
*
* @return
*/
@FormUrlEncoded
@POST("/revenge")
@POST("revenge")
Observable<VTResult<TabItemBean>> getTabItemBanner(@Field("category_id") int category_id);
/**
* 首页TabItem List
*
*
* @return
*/
@GET("/videoList")
@GET("videoList")
Observable<VTResult<VTVideoListBean>> getVideoList(@Query("category_id") int category_id, @Query("current_page") int current, @Query("page_size") int pageSize, @Query("search") String search);
/**
* 播放上报历史
*
*
* @return
*/
@FormUrlEncoded
@POST("/createHistory")
@POST("createHistory")
Observable<VTResult> createVideoHistory(@Field("short_play_id") int shorplayId, @Field("video_id") int videoId);
@ -120,7 +120,7 @@ public interface VTApiService {
*
* @return
*/
@GET("/search/hots")
@GET("search/hots")
Observable<VTResult<VTVideoListBean>> getSearchHotList();
/**
@ -128,62 +128,70 @@ public interface VTApiService {
*
* @return
*/
@GET("/search")
@GET("search")
Observable<VTResult<VTVideoListBean>> getSearchContentList(@Query("search") String search);
/**
* 搜索点击上报
*
*
* @return
*/
@FormUrlEncoded
@POST("/search/click")
@POST("search/click")
Observable<VTResult> searchClick(@Field("short_play_id") int shorplayId);
/**
* 首页推荐列表
*
*
* @return
*/
@GET("/getRecommands")
@GET("getRecommands")
Observable<VTResult<VTVideoExploreListBean>> getExploreList(@Query("current_page") int current, @Query("page_size") int pageSize);
/**
* 收藏
*
*
* @return
*/
@FormUrlEncoded
@POST("/collect")
@POST("collect")
Observable<VTResult> collect(@Field("short_play_id") int shorplayId, @Field("video_id") int videoId);
/**
* 取消收藏
*
*
* @return
*/
@FormUrlEncoded
@POST("/cancelCollect")
@POST("cancelCollect")
Observable<VTResult> cancelCollect(@Field("short_play_id") int shorplayId);
/**
* 获取用户信息
*
*
* @return
*/
@GET("/customer/info")
@GET("customer/info")
Observable<VTResult<VTUserInfoBean>> getUserInfo();
/**
*
*
* @return
*/
@GET("myHistorys")
Observable<VTResult<VTVideoListBean>> getVideoHistoryList(@Query("current_page") int currentpage, @Query("page_size") int pageSize);
/**
* 获取观看历史列表
*
* @return
*/
@GET("/myHistorys")
Observable<VTResult<VTVideoListBean>> getVideoHistoryList(@Query("current_page") int currentpage, @Query("page_size") int pageSize);
@GET("myCollections")
Observable<VTResult<VTVideoListBean>> getFollowList(@Query("current_page") int currentpage, @Query("page_size") int pageSize);
}

View File

@ -10,7 +10,9 @@ import java.net.UnknownHostException;
import java.text.ParseException;
import io.reactivex.observers.DisposableObserver;
import okhttp3.Interceptor;
import retrofit2.HttpException;
import retrofit2.Response;
public abstract class VTBaseObserver<T> extends DisposableObserver<T> {
/**

View File

@ -1,99 +0,0 @@
package com.viontv.app.api;
import com.google.gson.JsonParseException;
import org.json.JSONException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.text.ParseException;
import io.reactivex.observers.DisposableObserver;
import retrofit2.HttpException;
public abstract class VTBaseObserver1<T> extends DisposableObserver<T> {
/**
* 解析数据失败
*/
public static final int PARSE_ERROR = 1001;
/**
* 网络问题
*/
public static final int BAD_NETWORK = 1002;
/**
* 连接错误
*/
public static final int CONNECT_ERROR = 1003;
/**
* 连接超时
*/
public static final int CONNECT_TIMEOUT = 1004;
@Override
public void onNext(T o) {
VTResult1 model = (VTResult1) o;
if (model.code == 0) {
onSuccess(o);
} else {
onError(model.code, model.msg);
}
}
@Override
public void onError(Throwable e) {
if (e instanceof HttpException) {
// HTTP错误
onException(BAD_NETWORK);
} else if (e instanceof ConnectException
|| e instanceof UnknownHostException) {
// 连接错误
onException(CONNECT_ERROR);
} else if (e instanceof InterruptedIOException) {
// 连接超时
onException(CONNECT_TIMEOUT);
} else if (e instanceof JsonParseException
|| e instanceof JSONException
|| e instanceof ParseException) {
// 解析错误
onException(PARSE_ERROR);
} else {
if (e != null) {
onError(409, e.toString());
} else {
onError(407, "未知错误");
}
}
}
private void onException(int unknownError) {
switch (unknownError) {
case CONNECT_ERROR:
onError(CONNECT_ERROR, "连接错误");
break;
case CONNECT_TIMEOUT:
onError(CONNECT_TIMEOUT, "连接超时");
break;
case BAD_NETWORK:
onError(BAD_NETWORK, "网络问题");
break;
case PARSE_ERROR:
onError(PARSE_ERROR, "宇宙也是有尽头的");
break;
default:
break;
}
}
@Override
public void onComplete() {
}
public abstract void onSuccess(T o);
public abstract void onError(int code, String msg);
}

View File

@ -1,101 +0,0 @@
package com.viontv.app.api;
import com.google.gson.JsonParseException;
import org.json.JSONException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.text.ParseException;
import io.reactivex.observers.DisposableObserver;
import retrofit2.HttpException;
public abstract class VTBaseObserverPrize<T> extends DisposableObserver<T> {
/**
* 解析数据失败
*/
public static final int PARSE_ERROR = 1001;
/**
* 网络问题
*/
public static final int BAD_NETWORK = 1002;
/**
* 连接错误
*/
public static final int CONNECT_ERROR = 1003;
/**
* 连接超时
*/
public static final int CONNECT_TIMEOUT = 1004;
@Override
public void onNext(T o) {
VTResultPrize model = (VTResultPrize) o;
if (model.code == 0) {
onSuccess(o);
} else {
onError(model.code, model.msg);
}
}
@Override
public void onError(Throwable e) {
if (e instanceof HttpException) {
// HTTP错误
onException(BAD_NETWORK);
} else if (e instanceof ConnectException
|| e instanceof UnknownHostException) {
// 连接错误
onException(CONNECT_ERROR);
} else if (e instanceof InterruptedIOException) {
// 连接超时
onException(CONNECT_TIMEOUT);
} else if (e instanceof JsonParseException
|| e instanceof JSONException
|| e instanceof ParseException) {
// 解析错误
onException(PARSE_ERROR);
} else {
if (e != null) {
onError(409, e.toString());
} else {
onError(407, "未知错误");
}
}
}
private void onException(int unknownError) {
switch (unknownError) {
case CONNECT_ERROR:
onError(CONNECT_ERROR, "连接错误");
break;
case CONNECT_TIMEOUT:
onError(CONNECT_TIMEOUT, "连接超时");
break;
case BAD_NETWORK:
onError(BAD_NETWORK, "网络问题");
break;
case PARSE_ERROR:
onError(PARSE_ERROR, "宇宙也是有尽头的");
break;
default:
break;
}
}
@Override
public void onComplete() {
}
public abstract void onSuccess(T o);
public abstract void onError(int code, String msg);
}

View File

@ -0,0 +1,40 @@
package com.viontv.app.api;
import android.util.Log;
import com.viontv.app.utils.VTDecyrptUtils;
import okhttp3.Interceptor;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.io.IOException;
public class VTBodyloadInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response k_center = chain.proceed(chain.request());
if (k_center.body() != null && k_center.body().contentType() != null) {
String activity = k_center.body().contentType().toString();
String circle = k_center.body().string();
String str =circle;
Log.i("okhttp",circle+" ");
try{
str = VTDecyrptUtils.decrypt(circle);
}catch (Exception e){
}
Log.i("okhttp str",str+" ");
ResponseBody current = ResponseBody.create(k_center.body().contentType(), str);
return k_center.newBuilder().body(current).build();
} else {
return k_center;
}
}
}

View File

@ -22,12 +22,11 @@ public class VTHeaderInterceptor implements Interceptor {
Request request = chain.request().newBuilder()
.addHeader("Content-Type", "application/json")
.addHeader("authorization", SharePreferenceUtils.getString(SharePreferenceUtils.auth,""))
.addHeader("security","false")
// .addHeader("security","true")
.addHeader("lang-key","en")
.addHeader("device-id",GetAndroidUniqueMark.getUniqueId(VTApplication.getAppContext()))
.addHeader("system-type","android")
.addHeader("time_zone", TimeUtils.getCurrentTimeZone())
.build();
return chain.proceed(request);

View File

@ -1,24 +0,0 @@
package com.viontv.app.api;
import java.io.Serializable;
/**
* created by wmm on 2020/9/8
*/
public class VTResult1 implements Serializable {
public String msg;
public int code;
public boolean isSuccessful() {
return code == 0;
}
@Override
public String toString() {
return "Result{" +
"message='" + msg + '\'' +
", code=" + code +
'}';
}
}

View File

@ -1,34 +0,0 @@
package com.viontv.app.api;
import com.viontv.app.utils.VTGsonUtils;
import java.io.Serializable;
import java.util.List;
/**
* created by wmm on 2020/9/8
*/
public class VTResultPrize<T> implements Serializable {
public String msg;
public int code;
public T data;
public List<String> debug;
public boolean isSuccessful() {
return code == 0;
}
@Override
public String toString() {
return "Result{" +
"message='" + msg + '\'' +
", code=" + code +
", data=" + VTGsonUtils.beanToJSONString(data) +
", debug=" + VTGsonUtils.beanToJSONString(debug) +
'}';
}
}

View File

@ -12,6 +12,9 @@ public class ItemBean {
private int short_play_id;
private String name;
private String description;
@ -34,15 +37,38 @@ public class ItemBean {
private int episode_total;
private int current_episode;
private int search_click_total;
private String updated_at;
private int short_play_video_id;
private int is_collect;
public String getUpdated_at() {
return updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
private List<String> category;
private List<SearchCateGoryItemBean> categoryList; //搜索结果
private boolean isDeleteSelector = false;
public boolean isDeleteSelector() {
return isDeleteSelector;
}
public void setDeleteSelector(boolean deleteSelector) {
isDeleteSelector = deleteSelector;
}
public int getId() {
return id;
@ -152,6 +178,14 @@ public class ItemBean {
return episode_total;
}
public int getCurrent_episode() {
return current_episode;
}
public void setCurrent_episode(int current_episode) {
this.current_episode = current_episode;
}
public void setEpisode_total(int episode_total) {
this.episode_total = episode_total;
}
@ -180,4 +214,20 @@ public class ItemBean {
public void setCategoryList(List<SearchCateGoryItemBean> categoryList) {
this.categoryList = categoryList;
}
public int getShort_play_video_id() {
return short_play_video_id;
}
public void setShort_play_video_id(int short_play_video_id) {
this.short_play_video_id = short_play_video_id;
}
public int getIs_collect() {
return is_collect;
}
public void setIs_collect(int is_collect) {
this.is_collect = is_collect;
}
}

View File

@ -260,7 +260,10 @@ public class VTVideoDetailsBean {
this.short_play_id = short_play_id;
}
protected ShortPlayInfo(Parcel in) {
public ShortPlayInfo(){
}
public ShortPlayInfo(Parcel in) {
all_coins = in.readInt();
buy_type = in.readInt();
collect_total = in.readInt();

View File

@ -55,10 +55,11 @@ public class VTMainActivity extends VTCommonActivity<ActivityMainVtBinding> impl
fragments.add(VTMeFragment);
fragmentAdapter = new VTFragmentAdapter(this);
fragmentAdapter.setFragmentList(fragments);
binding.container.setUserInputEnabled(false);
binding.container.setUserInputEnabled(false); //disaple scroll
binding.container.setAdapter(fragmentAdapter);
binding.container.setCurrentItem(START_INDEX, false);
binding.container.setOffscreenPageLimit(fragments.size());
binding.container.setOffscreenPageLimit(1);
binding.tvVtMainHome.setOnClickListener(this);
binding.tvVtMainExplore.setOnClickListener(this);

View File

@ -23,15 +23,15 @@ public abstract class VTCommonActivity<T> extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 调用 HibitStatusBarTools 类的 pageDarkMode 方法设置页面为深色模式
// 深色模式
VTStatusBarUtils.pageDarkMode(this, false);
// 设置窗口标志防止屏幕内容被截屏或录制
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
);
// 设置活动的屏幕方向为竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// Disable screenshots and screen recording
// getWindow().setFlags(
// WindowManager.LayoutParams.FLAG_SECURE,
// WindowManager.LayoutParams.FLAG_SECURE
// );
//
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
// 调用抽象方法 initinitView logic
init();
initView();

View File

@ -21,6 +21,7 @@ import com.viontv.app.VTApplication;
import com.viontv.app.api.VTResult;
import com.viontv.app.databinding.FragmentExploreVtBinding;
import com.viontv.app.databinding.FragmentMainVtBinding;
import com.viontv.app.model.ItemBean;
import com.viontv.app.model.VTVideoDetailsBean;
import com.viontv.app.model.VTVideoExploreBean;
import com.viontv.app.model.VTVideoExploreListBean;
@ -182,6 +183,7 @@ public class VTExploreFragment extends Fragment implements VTGooglePlayerExplore
} else {
mViewModel.collection(bean.getVideo_info().getShort_play_id(), bean.getVideo_info().getShort_play_video_id());
}
EventBus.getDefault().post(VTAppConstants.Constants_Video_Collection);
});
}
@ -220,6 +222,8 @@ public class VTExploreFragment extends Fragment implements VTGooglePlayerExplore
}
}
// @Subscribe(threadMode = ThreadMode.MAIN)
// public void onEventFa(BaseEventBus<HibitMyCollectionsBean.Data> event) {
// if (HibitAppConstants.Constants_Episodes_Series_DataFavorites.equals(event.getCode())) {
@ -249,12 +253,15 @@ public class VTExploreFragment extends Fragment implements VTGooglePlayerExplore
VTApplication.isCurrentPage = false;
if (getHomePlayerView() != null) getHomePlayerView().suspend();
}
}
@Override
public void onResume() {
super.onResume();
VTApplication.isCurrentPage = true;
if (getHomePlayerView() != null) getHomePlayerView().start();
}
@Override

View File

@ -24,6 +24,7 @@ import com.viontv.app.databinding.FragmentMainVtBinding;
import com.viontv.app.model.CateGoryItemBean;
import com.viontv.app.model.HomeTopBean;
import com.viontv.app.model.ItemBean;
import com.viontv.app.ui.adapter.VTTabCommonAdapter;
import com.viontv.app.utils.IntentUtils;
import java.util.ArrayList;
@ -113,38 +114,15 @@ public class VTHomeFragment extends Fragment {
titles.add(itemBean.getCategory_name());
listFragment.add(VTTabItemFragment.newInstance(itemBean.getCategory_id()));
}
CommunityAdapter adapter = new CommunityAdapter(getActivity(), titles, listFragment);
VTTabCommonAdapter adapter = new VTTabCommonAdapter(getActivity(), titles, listFragment);
binding.viewpager.setAdapter(adapter);
//把TabLayout选项卡布局和ViewPager2绑定在一起特别说明一下下面这行代码是官方给的特别好使
new TabLayoutMediator(binding.tablayout, binding.viewpager, (tab, position) -> tab.setText(titles.get(position))).attach();
}
public class CommunityAdapter extends FragmentStateAdapter {
private ArrayList<String> listTitle;
private List<Fragment> listFragment;
public CommunityAdapter(@NonNull FragmentActivity fragmentActivity, ArrayList<String> listTitle, List<Fragment> listFragment) {
super(fragmentActivity);
this.listTitle = listTitle;
this.listFragment = listFragment;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return listFragment.get(position);
}
@Override
public int getItemCount() {
return listFragment.size();
}
}
MyCountDownTimer myCountDownTimer;

View File

@ -186,6 +186,7 @@ public class VTTabItemFragment extends Fragment {
binding.banner.setAdapter(new VTBannerHomeAdapter(itemBeans)).
setCurrentItem(0, true)
.addBannerLifecycleObserver(this)
.setOnBannerListener((data, position) -> IntentUtils.startPlayerDetails(getActivity(), itemBeans.get(position).getShort_play_id(), 0))
.isAutoLoop(true);
binding.banner.start();

View File

@ -23,6 +23,7 @@ public class VTUserViewModel extends ViewModel {
private final MutableLiveData<VTResult<VTUserInfoBean>> userInfoLiveData = new MutableLiveData<>();
private final MutableLiveData<VTResult<VTVideoListBean>> userVideoHistoryLiveData = new MutableLiveData<>();
private final MutableLiveData<VTResult<VTVideoListBean>> userFollowListLiveData = new MutableLiveData<>();
public MutableLiveData<VTResult<VTUserInfoBean>> getGetUserInfoLiveData() {
@ -33,6 +34,10 @@ public class VTUserViewModel extends ViewModel {
return userVideoHistoryLiveData;
}
public MutableLiveData<VTResult<VTVideoListBean>> getUserFollowListLiveData() {
return userFollowListLiveData;
}
public void getUserInfo() {
VTApi.getInstance().getUserInfo()
.subscribeOn(Schedulers.io())
@ -71,5 +76,23 @@ public class VTUserViewModel extends ViewModel {
});
}
public void getFollowList(int currentPage,int pageSize){
VTApi.getInstance().getFollowList(currentPage, pageSize)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new VTBaseObserver<VTResult<VTVideoListBean>>() {
@Override
public void onSuccess(VTResult<VTVideoListBean> feedbackResp) {
userFollowListLiveData.setValue(feedbackResp);
}
@Override
public void onError(int code, String msg) {
Log.i("tag===", msg + "");
userFollowListLiveData.setValue(null);
}
});
}
}

View File

@ -0,0 +1,221 @@
package com.viontv.app.ui.activity.mylist;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import com.google.android.material.tabs.TabLayoutMediator;
import com.viontv.app.R;
import com.viontv.app.api.VTResult;
import com.viontv.app.databinding.FragmentMylistBinding;
import com.viontv.app.databinding.FragmentMylistFollowlistBinding;
import com.viontv.app.databinding.ItemHotSquareVtBinding;
import com.viontv.app.databinding.ItemMylistFollowlistVtBinding;
import com.viontv.app.model.VTVideoDetailsBean;
import com.viontv.app.ui.activity.basic.VTBaseEventBus;
import com.viontv.app.ui.activity.me.VTUserViewModel;
import com.viontv.app.ui.activity.play.VTVideoViewModel;
import com.viontv.app.ui.adapter.VTMyListFollowAdapter;
import com.viontv.app.ui.adapter.VTNineSquareAdapter;
import com.viontv.app.ui.adapter.VTTabCommonAdapter;
import com.viontv.app.utils.IntentUtils;
import com.viontv.app.utils.TimeUtils;
import com.viontv.app.utils.VTAppConstants;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
public class VTFollowListFragment extends Fragment {
VTUserViewModel mViewModel;
VTVideoViewModel vtVideoViewModel;
private FragmentMylistFollowlistBinding binding;
private int currentPage = 1;
private VTMyListFollowAdapter adapter;
private int deletePosition = -1;
//private ArrayList listDelete = new ArrayList();
public static VTFollowListFragment newInstance() {
return new VTFollowListFragment();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(VTUserViewModel.class);
vtVideoViewModel = new ViewModelProvider(this).get(VTVideoViewModel.class);
// TODO: Use the ViewModel
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
EventBus.getDefault().register(this);
binding = FragmentMylistFollowlistBinding.inflate(inflater);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initRequestData();
initAdapter();
initRefreshLayout();
// binding.layoutMylistfollowEmpty.setOnClickListener(v ->{
// currentPage=1;
// mViewModel.getFollowList(currentPage,10);
// });
logic();
}
public void setDelete(boolean isdelete){
adapter.setDelete(isdelete);
binding.layoutFollowDelete.setVisibility(isdelete?VISIBLE:GONE);
// if(!isdelete){
// listDelete.clear();
// }
binding.tvMylistFollowlistDeletetxt.setText(String.format(getString(R.string.delete_tv),0));
deletePosition =-1;
}
private void initRequestData(){
currentPage = 1;
mViewModel.getFollowList(currentPage,10);
}
private void initAdapter(){
binding.recyclerviewMylistFollow.setLayoutManager(new GridLayoutManager(getActivity(), 3));
adapter = new VTMyListFollowAdapter(getActivity(), ItemMylistFollowlistVtBinding.class);
adapter.setItemClickListener((data, holder) -> {
IntentUtils.startPlayerDetails(getActivity(), data.getShort_play_id(), 0);
});
adapter.setListener(position -> {
// listDelete.add(position);
deletePosition = position;
binding.tvMylistFollowlistDeletetxt.setText(String.format(getString(R.string.delete_tv),1));
});
binding.recyclerviewMylistFollow.setAdapter(adapter);
binding.layoutFollowDelete.setOnClickListener(v -> {
if(deletePosition>=0){
//cancel
vtVideoViewModel.cancelcollection(adapter.getItemData(deletePosition).getShort_play_id());
VTVideoDetailsBean.ShortPlayInfo shortPlayInfo = new VTVideoDetailsBean.ShortPlayInfo();
shortPlayInfo.setShort_play_id(adapter.getItemData(deletePosition).getShort_play_id());
shortPlayInfo.setCollect_total(adapter.getItemData(deletePosition).getCollect_total());
EventBus.getDefault().post(new VTBaseEventBus<>(VTAppConstants.Constants_Episodes_Series_DataExample, shortPlayInfo));
List<Fragment> fragments = getParentFragmentManager().getFragments();
Log.i(" ","fragments=="+fragments.size());
for (Fragment fragment:fragments){
if(fragment instanceof VTMyListFragment){
((VTMyListFragment)fragment).setCancelView();
setDelete(false);
}
}
}
});
binding.ivFollowEmpty.setOnClickListener(v -> initRequestData());
}
private void initRefreshLayout() {
binding.materialHeader.setColorSchemeColors(0xffF564B6,0xffF564B6,0xffF564B6,0xffF564B6,0xffF564B6);
binding.smartrefreshlayoutMylistFollow.setEnableRefresh(true);
binding.smartrefreshlayoutMylistFollow.setEnableLoadMore(true);
binding.smartrefreshlayoutMylistFollow.setOnRefreshListener(refreshlayout -> {
currentPage = 1;
mViewModel.getFollowList(currentPage,10);
});
binding.smartrefreshlayoutMylistFollow.setOnLoadMoreListener(refreshLayout -> {
currentPage++;
mViewModel.getFollowList(currentPage,10);
});
}
private void logic() {
mViewModel.getUserFollowListLiveData().observe(getViewLifecycleOwner(), vtResult -> {
binding.smartrefreshlayoutMylistFollow.finishLoadMore();
binding.smartrefreshlayoutMylistFollow.finishRefresh();
// binding.layoutMylistfollowEmpty.setVisibility(View.GONE);
binding.recyclerviewMylistFollow.setVisibility(VISIBLE);
binding.ivFollowEmpty.setVisibility(GONE);
if(vtResult!=null&&vtResult.data!=null&& !vtResult.data.getList().isEmpty()){
adapter.addDataList(vtResult.data.getList(), currentPage == 1);
}else{
// binding.layoutMylistfollowEmpty.setVisibility(View.VISIBLE);
binding.recyclerviewMylistFollow.setVisibility(GONE);
binding.ivFollowEmpty.setVisibility(VISIBLE);
}
Log.i("tag count","count=="+adapter.getItemCount());
List<Fragment> fragments = getParentFragmentManager().getFragments();
for (Fragment fragment:fragments){
if(fragment instanceof VTMyListFragment){
((VTMyListFragment)fragment).setDeleteView(binding.ivFollowEmpty.getVisibility()==GONE);
setDelete(false);
}
}
});
vtVideoViewModel.getCollectioncancelLiveData().observe(getViewLifecycleOwner(),vtResult -> {
initRequestData();
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(VTBaseEventBus<VTVideoDetailsBean.ShortPlayInfo> event) {
if (VTAppConstants.Constants_Episodes_Series_DataExample.equals(event.getCode())) {
initRequestData();
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(String event) {
if (VTAppConstants.Constants_Video_Collection.equals(event)) {
initRequestData();
}
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}

View File

@ -1,5 +1,8 @@
package com.viontv.app.ui.activity.mylist;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -10,14 +13,30 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import com.viontv.app.R;
import com.viontv.app.databinding.FragmentMainVtBinding;
import com.viontv.app.databinding.FragmentMylistBinding;
import com.viontv.app.model.CateGoryItemBean;
import com.viontv.app.ui.activity.home.MainViewModel;
import com.viontv.app.ui.activity.home.VTHomeFragment;
import com.viontv.app.ui.activity.home.VTHotFragment;
import com.viontv.app.ui.activity.home.VTTabItemFragment;
import com.viontv.app.ui.activity.home.VTTopFragment;
import com.viontv.app.ui.activity.me.VTUserViewModel;
import com.viontv.app.ui.adapter.VTTabCommonAdapter;
import java.util.ArrayList;
import java.util.List;
public class VTMyListFragment extends Fragment {
private MainViewModel mViewModel;
private FragmentMainVtBinding binding;
private FragmentMylistBinding binding;
private List<Fragment> listFragment;
public static VTMyListFragment newInstance() {
return new VTMyListFragment();
@ -26,7 +45,6 @@ public class VTMyListFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(MainViewModel.class);
// TODO: Use the ViewModel
}
@ -34,8 +52,67 @@ public class VTMyListFragment extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentMainVtBinding.inflate(inflater);
binding = FragmentMylistBinding.inflate(inflater);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initTab();
}
public void initTab(){
ArrayList<String> titles = new ArrayList<>();
titles.add(getString(R.string.tab_mylist_followlist));
titles.add(getString(R.string.tab_mylist_playlist));
listFragment = new ArrayList<>();
listFragment.add(VTFollowListFragment.newInstance());
listFragment.add(VTPlayListFragment.newInstance());
VTTabCommonAdapter adapter = new VTTabCommonAdapter(getActivity(), titles, listFragment);
binding.viewpager.setAdapter(adapter);
//把TabLayout选项卡布局和ViewPager2绑定在一起特别说明一下下面这行代码是官方给的特别好使
new TabLayoutMediator(binding.tablayoutMylist, binding.viewpager, (tab, position) -> tab.setText(titles.get(position))).attach();
binding.tablayoutMylist.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
binding.ivMylistDelete.setVisibility(tab.getPosition()==0?VISIBLE:GONE);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
binding.ivMylistDelete.setOnClickListener(v -> {
binding.tvMylistCancel.setVisibility(VISIBLE);
binding.ivMylistDelete.setVisibility(GONE);
((VTFollowListFragment)(listFragment.get(0))).setDelete(true);
});
binding.tvMylistCancel.setOnClickListener(v -> {
binding.tvMylistCancel.setVisibility(GONE);
binding.ivMylistDelete.setVisibility(VISIBLE);
((VTFollowListFragment)(listFragment.get(0))).setDelete(false);
});
}
public void setCancelView(){
binding.tvMylistCancel.setVisibility(GONE);
binding.ivMylistDelete.setVisibility(VISIBLE);
}
public void setDeleteView(boolean isVisible){
binding.tvMylistCancel.setVisibility(GONE);
binding.ivMylistDelete.setVisibility(isVisible?VISIBLE:GONE);
}
}

View File

@ -0,0 +1,160 @@
package com.viontv.app.ui.activity.mylist;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import com.google.android.material.tabs.TabLayoutMediator;
import com.viontv.app.R;
import com.viontv.app.api.VTResult;
import com.viontv.app.databinding.FragmentMylistBinding;
import com.viontv.app.databinding.FragmentMylistFollowlistBinding;
import com.viontv.app.databinding.FragmentMylistPlaylistBinding;
import com.viontv.app.databinding.ItemHotSquareVtBinding;
import com.viontv.app.databinding.ItemMylistFollowlistVtBinding;
import com.viontv.app.databinding.ItemMylistPlaylistVtBinding;
import com.viontv.app.model.VTVideoDetailsBean;
import com.viontv.app.ui.activity.basic.VTBaseEventBus;
import com.viontv.app.ui.activity.me.VTUserViewModel;
import com.viontv.app.ui.adapter.VTMyListFollowAdapter;
import com.viontv.app.ui.adapter.VTMyListPlayAdapter;
import com.viontv.app.ui.adapter.VTNineSquareAdapter;
import com.viontv.app.ui.adapter.VTTabCommonAdapter;
import com.viontv.app.utils.IntentUtils;
import com.viontv.app.utils.TimeUtils;
import com.viontv.app.utils.VTAppConstants;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
public class VTPlayListFragment extends Fragment {
VTUserViewModel mViewModel;
private FragmentMylistPlaylistBinding binding;
private int currentPage = 1;
private VTMyListPlayAdapter adapter;
public static VTPlayListFragment newInstance() {
return new VTPlayListFragment();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(VTUserViewModel.class);
// TODO: Use the ViewModel
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
EventBus.getDefault().register(this);
binding = FragmentMylistPlaylistBinding.inflate(inflater);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initRequestData();
initAdapter();
initRefreshLayout();
// binding.layoutMylistfollowEmpty.setOnClickListener(v ->{
// currentPage=1;
// mViewModel.getFollowList(currentPage,10);
// });
logic();
}
private void initRequestData(){
currentPage = 1;
mViewModel.getHistory(currentPage,10);
}
private void initAdapter(){
binding.recyclerviewMylistPlay.setLayoutManager(new GridLayoutManager(getActivity(), 3));
adapter = new VTMyListPlayAdapter(getActivity(), ItemMylistPlaylistVtBinding.class);
adapter.setItemClickListener((data, holder) -> {
IntentUtils.startPlayerDetails(getActivity(), data.getShort_play_id(), 0);
});
binding.recyclerviewMylistPlay.setAdapter(adapter);
binding.ivPlaylistEmpty.setOnClickListener(v -> initRequestData());
}
private void initRefreshLayout() {
binding.materialHeaderPlaylist.setColorSchemeColors(0xffF564B6,0xffF564B6,0xffF564B6,0xffF564B6,0xffF564B6);
binding.smartrefreshlayoutMylistPlay.setEnableRefresh(true);
binding.smartrefreshlayoutMylistPlay.setEnableLoadMore(true);
binding.smartrefreshlayoutMylistPlay.setOnRefreshListener(refreshlayout -> {
currentPage = 1;
mViewModel.getHistory(currentPage,10);
});
binding.smartrefreshlayoutMylistPlay.setOnLoadMoreListener(refreshLayout -> {
currentPage++;
mViewModel.getHistory(currentPage,10);
});
}
private void logic() {
mViewModel.getUserVideoHistoryLiveData().observe(getViewLifecycleOwner(), vtResult -> {
binding.smartrefreshlayoutMylistPlay.finishLoadMore();
binding.smartrefreshlayoutMylistPlay.finishRefresh();
// binding.layoutMylistfollowEmpty.setVisibility(View.GONE);
binding.recyclerviewMylistPlay.setVisibility(View.VISIBLE);
binding.ivPlaylistEmpty.setVisibility(GONE);
Log.i("tag","result==="+vtResult.data);
if(vtResult!=null&&vtResult.data!=null&& !vtResult.data.getList().isEmpty()){
adapter.addDataList(vtResult.data.getList(), currentPage == 1);
}else{
binding.recyclerviewMylistPlay.setVisibility(GONE);
binding.ivPlaylistEmpty.setVisibility(VISIBLE);
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(String event) {
if (VTAppConstants.Constants_PlayerView_CreateHistoryEvent.equals(event)) {
currentPage = 1;
mViewModel.getHistory(1, 10);
}
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}

View File

@ -399,7 +399,7 @@ public class VTVideoPlayerActivity extends VTCommonActivity<ActivityVideoDetails
public void run() {
if (shortVideoInfo != null) {
if (shortVideoInfo.isIs_collect()) {
vtViewModel.cancelcollection(shortVideoInfo.getShort_id());
vtViewModel.cancelcollection(shortVideoInfo.getShort_play_id());
} else {
vtViewModel.collection(shortVideoInfo.getShort_play_id(), episode.getId());
}

View File

@ -55,7 +55,17 @@ public class VTSearchActivity extends VTCommonActivity<ActivitySearchVtBinding>
});
binding.rvVtSearchHot.setAdapter(adapter);
vtSearchViewModel.getHotList();
binding.ivBackSearch.setOnClickListener(v -> finish());
binding.ivBackSearch.setOnClickListener(v -> {
if(binding.layoutSearchData.getVisibility()==VISIBLE){
getHistoryData();
searchDataAdapter.addDataList(null, true);
binding.layoutSearchHot.setVisibility(VISIBLE);
binding.layoutSearchHistory.setVisibility(VISIBLE);
binding.layoutSearchData.setVisibility(GONE);
}else {
finish();
}
});
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL);
binding.rvVtSearchHistory.setLayoutManager(staggeredGridLayoutManager);

View File

@ -29,7 +29,7 @@ public class VTBannerHomeAdapter extends BannerAdapter<ItemBean, VTBannerHomeAda
imageView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
return new BannerHomeViewHolder(imageView);
}

View File

@ -0,0 +1,90 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
package com.viontv.app.ui.adapter;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.viontv.app.R;
import com.viontv.app.databinding.ItemHotSquareVtBinding;
import com.viontv.app.databinding.ItemMylistFollowlistVtBinding;
import com.viontv.app.model.ItemBean;
public class VTMyListFollowAdapter
extends VTCommonAdapter<ItemBean, ItemMylistFollowlistVtBinding> {
public ItemClickDeleteListener listener;
public void setListener(ItemClickDeleteListener listener) {
this.listener = listener;
}
public interface ItemClickDeleteListener{
void itemDelete(int position);
}
private Context mcontext;
private boolean isDelete = false;
public boolean isDelete() {
return isDelete;
}
public int deletePostion = -1;
public void setDelete(boolean delete) {
isDelete = delete;
deletePostion =-1;
notifyDataSetChanged();
}
public VTMyListFollowAdapter(
Context context, Class<ItemMylistFollowlistVtBinding> viewBinding) {
super(context, viewBinding);
this.mcontext = context;
}
@Override
public void onBindViewHolder(
ItemMylistFollowlistVtBinding binding,
int position,
ItemBean data,
int bingingAdapterPosition) {
if (data != null) {
Glide.with(mcontext)
.load(data.getImage_url())
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
.into(binding.ivMylistFollowlistItem);
binding.tvMylistFollowlistName.setText(data.getName());
binding.ivMylistSelector.setVisibility(GONE);
if(isDelete){
binding.ivMylistSelector.setVisibility(VISIBLE);
binding.ivMylistSelector.setImageResource(R.mipmap.ic_unselect_circle);
if(deletePostion==bingingAdapterPosition){
binding.ivMylistSelector.setImageResource(R.mipmap.ic_selected_circle);
}
binding.ivMylistSelector.setOnClickListener(v -> {
if(listener!=null){
if(deletePostion!=-1){
notifyItemChanged(deletePostion);
}
deletePostion = bingingAdapterPosition;
listener.itemDelete(bingingAdapterPosition);
notifyItemChanged(bingingAdapterPosition);
}
});
}
}
}
}

View File

@ -0,0 +1,57 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
package com.viontv.app.ui.adapter;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.content.Context;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.viontv.app.R;
import com.viontv.app.databinding.ItemMylistFollowlistVtBinding;
import com.viontv.app.databinding.ItemMylistPlaylistVtBinding;
import com.viontv.app.model.ItemBean;
import com.viontv.app.utils.TimeUtils;
import java.text.DecimalFormat;
public class VTMyListPlayAdapter
extends VTCommonAdapter<ItemBean, ItemMylistPlaylistVtBinding> {
private Context mcontext;
public VTMyListPlayAdapter(
Context context, Class<ItemMylistPlaylistVtBinding> viewBinding) {
super(context, viewBinding);
this.mcontext = context;
}
@Override
public void onBindViewHolder(
ItemMylistPlaylistVtBinding binding,
int position,
ItemBean data,
int bingingAdapterPosition) {
if (data != null) {
Glide.with(mcontext)
.load(data.getImage_url())
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.NONE))
.into(binding.ivMylistPlayItem);
binding.tvMylistPlaylistName.setText(data.getName());
binding.tvMylistPlaylistEp.setText(String.format(mcontext.getString(R.string.mylist_playlist_process),data.getCurrent_episode(),data.getEpisode_total()));
binding.tvMylistPlayProgress.setText(TimeUtils.precess(data.getCurrent_episode(),data.getEpisode_total())+"%");
}
}
}

View File

@ -0,0 +1,34 @@
package com.viontv.app.ui.adapter;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
import java.util.List;
public class VTTabCommonAdapter extends FragmentStateAdapter {
private ArrayList<String> listTitle;
private List<Fragment> listFragment;
public VTTabCommonAdapter(@NonNull FragmentActivity fragmentActivity, ArrayList<String> listTitle, List<Fragment> listFragment) {
super(fragmentActivity);
this.listTitle = listTitle;
this.listFragment = listFragment;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return listFragment.get(position);
}
@Override
public int getItemCount() {
return listFragment.size();
}
}

View File

@ -6,6 +6,8 @@ package com.viontv.app.ui.adapter;
import android.content.Context;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;

View File

@ -45,7 +45,7 @@ public class VTUserVideoHistoryAdapter
.load(data.getImage_url())
.apply(new RequestOptions().diskCacheStrategy(DiskCacheStrategy.RESOURCE))
.into(binding.ivHistoryItem);
binding.tvHistoryProgress.setText(TimeUtils.precess(data.getCurrent_episode(),data.getEpisode_total())+"%");
}
}

View File

@ -212,7 +212,7 @@ public class VTHomeGoogleExoPlayerView extends FrameLayout {
}
public void setMedia(VTVideoExploreBean bean) {
VTAppConstants.isCanPlay = true;
tv_title_player.setText(bean.getName());
// if (TranslatesUtils.translates() != null) {

View File

@ -63,4 +63,13 @@ public class TimeUtils {
DecimalFormat df = new DecimalFormat(pattern.toString());
return df.format(value);
}
public static String precess(int current_episode,int episode_total){
DecimalFormat df = new DecimalFormat("###.00");
double current = Double.parseDouble(df.format(current_episode));
double total = Double.parseDouble(df.format(episode_total));
double result = Double.parseDouble(df.format(current/total))*100;
DecimalFormat df2 = new DecimalFormat("###");
return df2.format(result);
}
}

View File

@ -32,6 +32,8 @@ public class VTAppConstants {
public static final String Constants_Google_PLAYER_STATUS_FINISH_DETAIL =
"constants_google_player_status_finish_detail";
public static final String Constants_Episodes_Series_DataExample = "Constants_Episodes_Series_DataExample";
public static final String Constants_Video_Collection = "Constants_Video_Collection";
public static final String Constants_Video_CancelCollection = "Constants_Video_CancelCollection";
public static boolean isCanPlay = true;
public static boolean isLock = false;

View File

@ -0,0 +1,70 @@
package com.viontv.app.utils;
public class VTDecyrptUtils {
public static final char EN_STR_TAG = '$';
/**
* decyrpt data
* @param data
* @return
*/
public static String decrypt(String data) {
return new String(deStrBytes(data), java.nio.charset.StandardCharsets.UTF_8);
}
public static byte[] deStrBytes(String data) {
if (data == null || data.isEmpty() || data.charAt(0) != EN_STR_TAG) {
throw new IllegalArgumentException("Invalid encoded string");
}
String hexData = data.substring(1);
int len = hexData.length();
byte[] result = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
result[i / 2] = (byte) Integer.parseInt(hexData.substring(i, i + 2), 16);
}
return deDat(result);
}
public static byte[] deDat(byte[] data) {
if (data.length == 0) {
return data;
}
int saltLen = data[0];
byte[] salt = new byte[saltLen];
System.arraycopy(data, 1, salt, 0, saltLen);
byte[] encrypted = new byte[data.length - saltLen - 1];
System.arraycopy(data, 1 + saltLen, encrypted, 0, encrypted.length);
return deWithSalt(encrypted, salt);
}
public static byte[] deWithSalt(byte[] data, byte[] salt) {
byte[] decryptedData = cxEd(data);
return removeSalt(decryptedData, salt);
}
public static byte[] cxEd(byte[] data) {
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++) {
result[i] = (byte) (data[i] ^ 0xFF);
}
return result;
}
public static byte[] removeSalt(byte[] data, byte[] salt) {
if (salt.length == 0) return data;
byte[] result = new byte[data.length];
for (int i = 0; i < data.length; i++) {
byte s = salt[i % salt.length];
result[i] = calRemoveSalt(data[i], s);
}
return result;
}
public static byte calRemoveSalt(byte v, byte s) {
return (v >= s) ? (byte) (v - s) : (byte) (0xFF - (s - v) + 1);
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/white">
<!-- 默认显⽰效果-->
<item>
<shape android:shape="rectangle">
<solid android:color="#66000000" />
<corners android:topLeftRadius="@dimen/dp_7"
android:bottomRightRadius="@dimen/dp_7"/>
</shape>
</item>
</ripple>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/white">
<!-- 默认显⽰效果-->
<item>
<shape android:shape="rectangle">
<solid android:color="#ffffff" />
<corners android:radius="@dimen/dp_3" />
</shape>
</item>
</ripple>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/white">
<!-- 默认显⽰效果-->
<item>
<shape android:shape="rectangle">
<stroke android:color="#9d9d9d" android:width="@dimen/dp_1"/>
<corners android:radius="@dimen/dp_30" />
</shape>
</item>
</ripple>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/ic_selected_circle" android:state_selected="true" />
<item android:drawable="@mipmap/ic_unselect_circle" android:state_selected="false" />
</selector>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:gravity="center" android:width="@dimen/dp_19" android:height="@dimen/dp_4">
<!-- <bitmap-->
<!-- android:gravity="top|center_horizontal"-->
<!-- android:src="@drawable/cornor_ffffff_3dp"/>-->
<shape android:shape="rectangle">
<solid android:color="#ffffff" />
<corners android:radius="@dimen/dp_3" />
</shape>
</item>
</layer-list>

View File

@ -71,7 +71,8 @@
android:layout_alignTop="@+id/tv_search_history_txt"
android:layout_alignBottom="@+id/tv_search_history_txt"
android:layout_alignParentEnd="true"
android:src="@mipmap/ic_history_delete" />
android:src="@mipmap/ic_delete"
app:tint="@android:color/white"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_vt_search_history"

View File

@ -43,6 +43,7 @@
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="0dp"
app:banner_radius="@dimen/dp_10"
app:layout_constraintDimensionRatio="345:183"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

View File

@ -35,6 +35,7 @@
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="0dp"
app:banner_radius="@dimen/dp_10"
app:layout_constraintDimensionRatio="345:183"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

View File

@ -29,6 +29,8 @@
android:gravity="center_vertical"
android:drawablePadding="@dimen/dp_7"
android:textColor="#38ffffff"
android:maxLines="1"
android:ellipsize="end"
android:textSize="@dimen/sp_12"
app:drawableStartCompat="@mipmap/iv_homefragment_search" />
</FrameLayout>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/iv_homefragment_bg"
>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="1dp"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.7" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout_mylist"
android:layout_width="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline"
android:layout_marginTop="@dimen/dp_55"
android:layout_height="@dimen/dp_40"
android:layout_centerVertical="true"
app:layout_constraintTop_toTopOf="parent"
android:background="@android:color/transparent"
app:tabBackground="@android:color/transparent"
app:tabIndicator="@drawable/tabindicator_item_mylist"
app:tabIndicatorColor="@android:color/white"
app:tabIndicatorGravity="bottom"
app:tabIndicatorFullWidth="false"
app:tabInlineLabel="false"
app:tabIndicatorHeight="@dimen/dp_8"
app:tabMinWidth="@dimen/dp_40"
app:tabMode="fixed"
app:tabPaddingBottom="@dimen/dp_3"
app:tabPaddingEnd="5dp"
app:tabPaddingStart="5dp"
app:tabRippleColor="@null"
app:tabSelectedTextColor="#e6ffffff"
app:tabTextAppearance="@style/MyBgTablayoutstyle"
app:tabSelectedTextAppearance="@style/MyBgTablayoutSelectstyle"
app:tabTextColor="#888888" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="@dimen/dp_10"
app:layout_constraintTop_toBottomOf="@+id/tablayout_mylist"
app:layout_constraintBottom_toBottomOf="parent"
android:overScrollMode="never" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_mylist_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dp_14"
android:visibility="gone"
android:src="@mipmap/ic_delete"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tablayout_mylist"
app:layout_constraintBottom_toBottomOf="@+id/tablayout_mylist"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_mylist_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/dp_14"
android:text="@string/cancel_tv"
android:textColor="@android:color/white"
android:textStyle="bold"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/tablayout_mylist"
app:layout_constraintBottom_toBottomOf="@+id/tablayout_mylist"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smart.refresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/smartrefreshlayout_mylist_follow"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.scwang.smart.refresh.header.MaterialHeader
android:layout_width="match_parent"
android:id="@+id/materialHeader"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_5"
android:layout_marginEnd="@dimen/dp_15"
android:id="@+id/recyclerview_mylist_follow"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_follow_empty"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true"
app:srcCompat="@mipmap/ic_empty_data"
android:layout_height="wrap_content"/>
<FrameLayout
android:layout_marginStart="@dimen/dp_20"
android:layout_marginEnd="@dimen/dp_20"
android:id="@+id/layout_follow_delete"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:visibility="gone"
android:layout_marginBottom="@dimen/dp_51"
android:background="@drawable/cornor_stroke_9d9d9d_30dp"
android:layout_height="@dimen/dp_47">
<TextView
android:id="@+id/tv_mylist_followlist_deletetxt"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:drawablePadding="@dimen/dp_7"
android:layout_height="wrap_content"
android:textSize="@dimen/sp_14"
android:textColor="#9d9d9d"
android:drawableStart="@mipmap/ic_delete"/>
</FrameLayout>
</RelativeLayout>
<com.scwang.smart.refresh.footer.ClassicsFooter
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srlTextFinish="Load Success"
app:srlTextLoading="Loading…" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smart.refresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/smartrefreshlayout_mylist_play"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.scwang.smart.refresh.header.MaterialHeader
android:id="@+id/materialHeader_playlist"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_5"
android:layout_marginEnd="@dimen/dp_15"
android:id="@+id/recyclerview_mylist_play"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_playlist_empty"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true"
app:srcCompat="@mipmap/ic_empty_data"
android:layout_height="wrap_content"/>
</RelativeLayout>
<com.scwang.smart.refresh.footer.ClassicsFooter
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srlTextFinish="Load Success"
app:srlTextLoading="Loading…" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>

View File

@ -24,8 +24,8 @@
android:id="@+id/iv_hot_explore_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:minHeight="@dimen/dp_100"
android:scaleType="centerCrop"
android:minHeight="@dimen/dp_110"
app:layout_constraintDimensionRatio="82:110"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@ -18,9 +18,9 @@
android:id="@+id/iv_hometab_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:scaleType="centerCrop"
android:minHeight="@dimen/dp_89"
app:layout_constraintDimensionRatio="169:89"
app:layout_constraintDimensionRatio="h:1:1.9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@ -24,7 +24,7 @@
android:id="@+id/iv_hot_square_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
android:scaleType="centerCrop" />
<ImageButton
android:layout_width="@dimen/dp_22"

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_hot_square"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:layout_marginTop="@dimen/dp_10">
<androidx.cardview.widget.CardView
android:id="@+id/cardview_mylist_followlist"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="107:154"
app:cardCornerRadius="@dimen/dp_10"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_mylist_followlist_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_mylist_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:padding="@dimen/dp_10"
android:visibility="gone"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/tv_mylist_followlist_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_5"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@android:color/white"
android:textSize="@dimen/sp_13"
app:layout_constraintTop_toBottomOf="@+id/cardview_mylist_followlist" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_10"
android:layout_marginTop="@dimen/dp_10">
<androidx.cardview.widget.CardView
android:id="@+id/cardview_mylist_play"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="107:154"
app:cardCornerRadius="@dimen/dp_7"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_mylist_play_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_mylist_play_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@mipmap/ic_series_play"
android:background="@drawable/bg_videohistory_progress_7dp"
android:layout_marginEnd="@dimen/dp_5"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_12"
android:drawablePadding="@dimen/dp_3"
android:paddingTop="@dimen/dp_3"
android:paddingBottom="@dimen/dp_3"
android:textColor="@android:color/white"
android:textSize="@dimen/sp_9"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/tv_mylist_playlist_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_5"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@android:color/white"
android:textSize="@dimen/sp_13"
app:layout_constraintTop_toBottomOf="@+id/cardview_mylist_play" />
<TextView
android:id="@+id/tv_mylist_playlist_ep"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_5"
android:textColor="#8A899F"
app:layout_goneMarginTop="@dimen/dp_2"
android:textSize="@dimen/sp_11"
app:layout_constraintTop_toBottomOf="@+id/tv_mylist_playlist_name" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -6,10 +6,30 @@
android:layout_marginStart="@dimen/dp_10"
app:cardCornerRadius="@dimen/dp_7">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_history_item"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_history_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_history_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@mipmap/ic_series_play"
android:background="@drawable/bg_videohistory_progress_7dp"
android:layout_marginEnd="@dimen/dp_5"
android:paddingStart="@dimen/dp_12"
android:paddingEnd="@dimen/dp_12"
android:drawablePadding="@dimen/dp_3"
android:paddingTop="@dimen/dp_3"
android:paddingBottom="@dimen/dp_3"
android:textColor="@android:color/white"
android:textSize="@dimen/sp_9"
/>
</RelativeLayout>
</androidx.cardview.widget.CardView>

View File

@ -167,7 +167,9 @@
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_homeplayer_video"
android:layout_width="match_parent"
android:minHeight="@dimen/dp_66"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="49:66" />
</androidx.cardview.widget.CardView>

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -23,6 +23,12 @@
<string name="tabme_private_policy">Privacy Policy</string>
<string name="tabme_user_agreement">User Agreement</string>
<string name="tabme_about_us">About Us</string>
<string name="tab_mylist_followlist">Follow List</string>
<string name="tab_mylist_playlist">Play List</string>
<string name="mylist_playlist_process">EP.%d/EP.%d</string>
<string name="cancel_tv">Cancel</string>
<string name="delete_tv">Delete(%d)</string>
<string name="vt_network_error_please_check_the_network">Network error please check the network</string>

View File

@ -10,8 +10,11 @@
<style name="MyBgTablayoutstyle" parent="Base.Widget.Design.TabLayout">
<item name="android:textSize">@dimen/sp_16</item>
<item name="android:textSize">@dimen/sp_15</item>
</style>
<style name="MyBgTablayoutSelectstyle" parent="Base.Widget.Design.TabLayout">
<item name="android:textSize">@dimen/sp_16</item>
</style>
</resources>

Binary file not shown.