Browse Source

YCVideoPlayer

yangchong 7 years ago
parent
commit
b855d5cb9e
39 changed files with 2614 additions and 83 deletions
  1. 5 1
      app/src/main/java/org/yczbj/ycvideoplayer/api/constant/Constant.java
  2. 62 0
      app/src/main/java/org/yczbj/ycvideoplayer/api/http/news/NewsApi.java
  3. 44 0
      app/src/main/java/org/yczbj/ycvideoplayer/api/http/news/NewsModel.java
  4. 3 19
      app/src/main/java/org/yczbj/ycvideoplayer/base/BaseApplication.java
  5. 55 0
      app/src/main/java/org/yczbj/ycvideoplayer/base/BaseConfig.java
  6. 13 0
      app/src/main/java/org/yczbj/ycvideoplayer/base/BaseFragmentFactory.java
  7. 3 3
      app/src/main/java/org/yczbj/ycvideoplayer/base/mvp2/BaseList1Fragment.java
  8. 133 0
      app/src/main/java/org/yczbj/ycvideoplayer/base/mvp2/BaseList2Fragment.java
  9. 72 0
      app/src/main/java/org/yczbj/ycvideoplayer/service/InitializeService.java
  10. 7 0
      app/src/main/java/org/yczbj/ycvideoplayer/test/test3/ui/activity/DLMyFileTestActivity.java
  11. 126 36
      app/src/main/java/org/yczbj/ycvideoplayer/ui/home/view/fragment/HomeFragment.java
  12. 43 2
      app/src/main/java/org/yczbj/ycvideoplayer/ui/main/view/activity/MainActivity.java
  13. 105 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/NewsFragment.java
  14. 48 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/contract/INewsArticle.java
  15. 448 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/model/bean/NewsCommentBean.java
  16. 129 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/model/binder/NewsArticleImgViewBinder.java
  17. 114 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/model/binder/NewsArticleTextViewBinder.java
  18. 181 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/presenter/NewsArticlePresenter.java
  19. 43 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/view/adapter/NewsArticleAdapter.java
  20. 97 0
      app/src/main/java/org/yczbj/ycvideoplayer/ui/news/view/fragment/NewsArticleFragment.java
  21. 1 13
      app/src/main/java/org/yczbj/ycvideoplayer/ui/person/MeFragment.java
  22. 0 1
      app/src/main/java/org/yczbj/ycvideoplayer/ui/special/SpecialFragment.java
  23. 2 2
      app/src/main/java/org/yczbj/ycvideoplayer/ui/video/VideoFragment.java
  24. 2 2
      app/src/main/java/org/yczbj/ycvideoplayer/ui/video/view/fragment/VideoArticleFragment.java
  25. 25 0
      app/src/main/java/org/yczbj/ycvideoplayer/util/Register.java
  26. 117 0
      app/src/main/java/org/yczbj/ycvideoplayer/util/animation/AnimationViewUtil.java
  27. 179 0
      app/src/main/java/org/yczbj/ycvideoplayer/util/animation/AnimationsUtils.java
  28. 105 0
      app/src/main/java/org/yczbj/ycvideoplayer/util/animation/AnimatorUtils.java
  29. BIN
      app/src/main/res/drawable-xhdpi/icon_binding_hint.png
  30. BIN
      app/src/main/res/drawable-xxhdpi/icon_search_normal.png
  31. 8 0
      app/src/main/res/drawable/shape_search_bg.xml
  32. 19 0
      app/src/main/res/layout/activity_test_dl_my.xml
  33. 70 0
      app/src/main/res/layout/fragment_home.xml
  34. 107 0
      app/src/main/res/layout/item_news_article_img.xml
  35. 92 0
      app/src/main/res/layout/item_news_article_text.xml
  36. 7 4
      app/src/main/res/values/array.xml
  37. 120 0
      app/src/main/res/values/array_news.xml
  38. 23 0
      app/src/main/res/values/colors.xml
  39. 6 0
      app/src/main/res/values/styles.xml

+ 5 - 1
app/src/main/java/org/yczbj/ycvideoplayer/api/constant/Constant.java

@@ -31,13 +31,17 @@ public class Constant {
     public static final int SLIDABLE_EDGE = 1;
     public static final int SLIDABLE_FULL = 2;
 
+    public static final long CLICK_TIME = 500;
+
     public static final int[] ICONS_DRAWABLES = new int[]{
             R.mipmap.ic_launcher_circle,
             R.mipmap.ic_launcher_rect,
             R.mipmap.ic_launcher_square};
 
     public static final String[] ICONS_TYPE = new String[]{"circle", "rect", "square"};
-
     public static final String SP_NAME = "yc";
+    public static final String KEY_IS_LOGIN = "is_login";
+    public static final String KEY_NIGHT_STATE = "night_state";
+
 
 }

+ 62 - 0
app/src/main/java/org/yczbj/ycvideoplayer/api/http/news/NewsApi.java

@@ -0,0 +1,62 @@
+package org.yczbj.ycvideoplayer.api.http.news;
+
+
+import org.yczbj.ycvideoplayer.ui.news.model.bean.NewsCommentBean;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleBean;
+
+import io.reactivex.Observable;
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.http.GET;
+import retrofit2.http.Query;
+
+/**
+ * 参考 : https://github.com/hrscy/TodayNews/blob/master/news.json
+ */
+
+public interface NewsApi {
+
+    String HOST = "http://is.snssdk.com/";
+
+    /**
+     * 获取个性化新闻
+     * 深圳 http://is.snssdk.com/api/news/feed/v58/?iid=5034850950&device_id=6096495334&category=news_society
+     * 深圳 http://lf.snssdk.com/api/news/feed/v58/?iid=12507202490&device_id=37487219424&category=news_society
+     * 天津 http://ib.snssdk.com/api/news/feed/v58/?
+     * 北京 http://iu.snssdk.com/api/news/feed/v58/?
+     *
+     * @param iid      用户ID
+     * @param deviceId 设备ID
+     * @param category 新闻/图片/视频栏目
+     */
+    @GET("http://is.snssdk.com/api/news/feed/v58/")
+    Call<ResponseBody> getNewsArticle(
+            @Query("iid") String iid,
+            @Query("device_id") String deviceId,
+            @Query("category") String category);
+
+    @GET("http://is.snssdk.com/api/news/feed/v62/?iid=5034850950&device_id=6096495334&refer=1&count=20&aid=13")
+    Observable<MultiNewsArticleBean> getNewsArticle(
+            @Query("category") String category,
+            @Query("max_behot_time") String maxBehotTime);
+
+    @GET("http://lf.snssdk.com/api/news/feed/v62/?iid=12507202490&device_id=37487219424&refer=1&count=20&aid=13")
+    Observable<MultiNewsArticleBean> getNewsArticle2(
+            @Query("category") String category,
+            @Query("max_behot_time") String maxBehotTime);
+
+    /**
+     * 获取新闻评论
+     * 按热度排序
+     * http://is.snssdk.com/article/v53/tab_comments/?group_id=6314103921648926977&offset=0&tab_index=0
+     * 按时间排序
+     * http://is.snssdk.com/article/v53/tab_comments/?group_id=6314103921648926977&offset=0&tab_index=1
+     *
+     * @param groupId 新闻ID
+     * @param offset  偏移量
+     */
+    @GET("http://is.snssdk.com/article/v53/tab_comments/")
+    Observable<NewsCommentBean> getNewsComment(
+            @Query("group_id") String groupId,
+            @Query("offset") int offset);
+}

+ 44 - 0
app/src/main/java/org/yczbj/ycvideoplayer/api/http/news/NewsModel.java

@@ -0,0 +1,44 @@
+package org.yczbj.ycvideoplayer.api.http.news;
+
+
+import org.yczbj.ycvideoplayer.api.http.video.VideoApi;
+import org.yczbj.ycvideoplayer.api.manager.RetrofitWrapper;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleBean;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.VideoContentBean;
+
+import io.reactivex.Observable;
+
+
+/**
+ * Created by PC on 2017/8/21.
+ * 作者:PC
+ */
+
+public class NewsModel {
+
+    private static NewsModel model;
+    private NewsApi mApiService;
+    private static final String HOST = "http://toutiao.com/";
+
+    private NewsModel() {
+        mApiService = RetrofitWrapper
+                .getInstance(HOST)
+                .create(NewsApi.class);
+    }
+
+    public static NewsModel getInstance(){
+        if(model == null) {
+            model = new NewsModel();
+        }
+        return model;
+    }
+
+    public Observable<MultiNewsArticleBean> getNewsArticle(String category, String maxBehotTime) {
+        return mApiService.getNewsArticle(category,maxBehotTime);
+    }
+
+    public Observable<MultiNewsArticleBean> getNewsArticle2(String category, String maxBehotTime) {
+        return mApiService.getNewsArticle2(category,maxBehotTime);
+    }
+
+}

+ 3 - 19
app/src/main/java/org/yczbj/ycvideoplayer/base/BaseApplication.java

@@ -10,6 +10,7 @@ import com.blankj.utilcode.util.Utils;
 import com.liulishuo.filedownloader.FileDownloader;
 import com.liulishuo.filedownloader.connection.FileDownloadUrlConnection;
 
+import org.yczbj.ycvideoplayer.service.InitializeService;
 import org.yczbj.ycvideoplayer.util.LogUtils;
 
 import java.net.Proxy;
@@ -67,8 +68,8 @@ public class BaseApplication extends Application {
         super.onCreate();
         instance = this;
         initUtils();
-        LogUtils.logDebug = true;
-        initDownLoadLib();
+        //在子线程中初始化
+        InitializeService.start(this);
     }
 
     /**
@@ -120,23 +121,6 @@ public class BaseApplication extends Application {
     }
 
 
-    /**
-     * 初始化下载库
-     */
-    private void initDownLoadLib() {
-        FileDownloader.setupOnApplicationOnCreate(this)
-                .connectionCreator(new FileDownloadUrlConnection
-                        .Creator(new FileDownloadUrlConnection.Configuration()
-                        .connectTimeout(15_000)
-                        .readTimeout(15_000)
-                        .proxy(Proxy.NO_PROXY)
-                ))
-                .commit();
-
-        //最简单的初始化
-        //FileDownloader.setup(instance);
-    }
-
 
 }
 

+ 55 - 0
app/src/main/java/org/yczbj/ycvideoplayer/base/BaseConfig.java

@@ -0,0 +1,55 @@
+package org.yczbj.ycvideoplayer.base;
+
+
+import com.blankj.utilcode.util.SPUtils;
+
+import org.yczbj.ycvideoplayer.api.constant.Constant;
+
+/**
+ * ================================================
+ * 作    者:杨充
+ * 版    本:1.0
+ * 创建日期:2017/5/14
+ * 描    述:所有的配置
+ * 修订历史:
+ * ================================================
+ */
+public enum BaseConfig {
+
+    //对象
+    INSTANCE;
+
+    private boolean isLogin;
+    private boolean isNight;
+
+
+    public void initConfig(){
+        //是否是登录状态
+        isLogin = SPUtils.getInstance(Constant.SP_NAME).getBoolean(Constant.KEY_IS_LOGIN, false);
+        //初始化夜间模式
+        isNight = SPUtils.getInstance(Constant.SP_NAME).getBoolean(Constant.KEY_NIGHT_STATE,false);
+    }
+
+    public boolean isLogin() {
+        return isLogin;
+    }
+
+    public void setLogin(boolean login) {
+        SPUtils.getInstance(Constant.SP_NAME).put(Constant.KEY_IS_LOGIN,login);
+        this.isLogin = login;
+    }
+
+    public boolean getIsLogin(){
+        isLogin = SPUtils.getInstance(Constant.SP_NAME).getBoolean(Constant.KEY_IS_LOGIN, false);
+        return isLogin;
+    }
+
+    public boolean isNight() {
+        return isNight;
+    }
+
+    public void setNight(boolean night) {
+        SPUtils.getInstance(Constant.SP_NAME).put(Constant.KEY_NIGHT_STATE,night);
+        this.isNight = night;
+    }
+}

+ 13 - 0
app/src/main/java/org/yczbj/ycvideoplayer/base/BaseFragmentFactory.java

@@ -1,5 +1,6 @@
 package org.yczbj.ycvideoplayer.base;
 
+import org.yczbj.ycvideoplayer.ui.news.NewsFragment;
 import org.yczbj.ycvideoplayer.ui.video.VideoFragment;
 import org.yczbj.ycvideoplayer.ui.home.view.fragment.HomeFragment;
 import org.yczbj.ycvideoplayer.ui.person.MeFragment;
@@ -20,6 +21,7 @@ public class BaseFragmentFactory {
 
     private static BaseFragmentFactory mInstance;
     private HomeFragment mHomeFragment;
+    private NewsFragment mNewsFragment;
     private SpecialFragment mSpecialFragment;
     private VideoFragment mVideoFragment;
     private MeFragment mMeFragment;
@@ -49,6 +51,17 @@ public class BaseFragmentFactory {
         return mHomeFragment;
     }
 
+    public NewsFragment getNewsFragment() {
+        if (mNewsFragment == null) {
+            synchronized (BaseFragmentFactory.class) {
+                if (mNewsFragment == null) {
+                    mNewsFragment = new NewsFragment();
+                }
+            }
+        }
+        return mNewsFragment;
+    }
+
 
     public SpecialFragment getSpecialFragment() {
         if (mSpecialFragment == null) {

+ 3 - 3
app/src/main/java/org/yczbj/ycvideoplayer/base/mvp2/BaseListFragment.java → app/src/main/java/org/yczbj/ycvideoplayer/base/mvp2/BaseList1Fragment.java

@@ -15,7 +15,7 @@ import me.drakeet.multitype.Items;
 import me.drakeet.multitype.MultiTypeAdapter;
 
 
-public abstract class BaseListFragment<T extends IBasePresenter> extends BaseMVPLazyFragment<T> implements IBaseListView<T>, SwipeRefreshLayout.OnRefreshListener {
+public abstract class BaseList1Fragment<T extends IBasePresenter> extends BaseMVPLazyFragment<T> implements IBaseListView<T>, SwipeRefreshLayout.OnRefreshListener {
 
     public static final String TAG = "BaseListFragment";
     protected RecyclerView recyclerView;
@@ -61,7 +61,7 @@ public abstract class BaseListFragment<T extends IBasePresenter> extends BaseMVP
 
     @Override
     public void fetchData() {
-        observable = RxBus.getInstance().register(BaseListFragment.TAG);
+        observable = RxBus.getInstance().register(BaseList1Fragment.TAG);
         observable.subscribe(new Consumer<Integer>() {
             @Override
             public void accept(@NonNull Integer integer) throws Exception {
@@ -124,7 +124,7 @@ public abstract class BaseListFragment<T extends IBasePresenter> extends BaseMVP
 
     @Override
     public void onDestroy() {
-        RxBus.getInstance().unregister(BaseListFragment.TAG, observable);
+        RxBus.getInstance().unregister(BaseList1Fragment.TAG, observable);
         super.onDestroy();
     }
 }

+ 133 - 0
app/src/main/java/org/yczbj/ycvideoplayer/base/mvp2/BaseList2Fragment.java

@@ -0,0 +1,133 @@
+package org.yczbj.ycvideoplayer.base.mvp2;
+
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.View;
+
+import com.pedaily.yc.ycdialoglib.toast.ToastUtil;
+
+import org.yczbj.ycvideoplayer.R;
+import org.yczbj.ycvideoplayer.model.LoadingEndBean;
+import org.yczbj.ycvideoplayer.util.SettingUtil;
+
+import io.reactivex.Observable;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.functions.Consumer;
+import me.drakeet.multitype.Items;
+import me.drakeet.multitype.MultiTypeAdapter;
+
+
+public abstract class BaseList2Fragment<T extends IBasePresenter> extends BaseMVPLazyFragment<T> implements IBaseListView<T>, SwipeRefreshLayout.OnRefreshListener {
+
+    public static final String TAG = "BaseListFragment";
+    protected RecyclerView recyclerView;
+    protected SwipeRefreshLayout swipeRefreshLayout;
+    protected MultiTypeAdapter adapter;
+    protected Items oldItems = new Items();
+    protected boolean canLoadMore = false;
+    protected Observable<Integer> observable;
+
+    @Override
+    protected int attachLayoutId() {
+        return R.layout.base_refresh_recycler_view;
+    }
+
+    @Override
+    protected void initView(View view) {
+        recyclerView = view.findViewById(R.id.recyclerView);
+        recyclerView.setHasFixedSize(true);
+        swipeRefreshLayout = view.findViewById(R.id.refresh);
+        swipeRefreshLayout.setColorSchemeColors(SettingUtil.getInstance().getColor());
+        swipeRefreshLayout.setOnRefreshListener(this);
+    }
+
+    @Override
+    public void onShowLoading() {
+        swipeRefreshLayout.post(new Runnable() {
+            @Override
+            public void run() {
+                swipeRefreshLayout.setRefreshing(true);
+            }
+        });
+    }
+
+    @Override
+    public void onHideLoading() {
+        swipeRefreshLayout.post(new Runnable() {
+            @Override
+            public void run() {
+                swipeRefreshLayout.setRefreshing(false);
+            }
+        });
+    }
+
+    @Override
+    public void fetchData() {
+        observable = RxBus.getInstance().register(BaseList2Fragment.TAG);
+        observable.subscribe(new Consumer<Integer>() {
+            @Override
+            public void accept(@NonNull Integer integer) throws Exception {
+                adapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    @Override
+    public void onShowNetError() {
+        ToastUtil.showToast(getActivity(),getString(R.string.network_error));
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                adapter.setItems(new Items());
+                adapter.notifyDataSetChanged();
+                canLoadMore = false;
+            }
+        });
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // 设置下拉刷新的按钮的颜色
+        swipeRefreshLayout.setColorSchemeColors(SettingUtil.getInstance().getColor());
+    }
+
+    @Override
+    public void onShowNoMore() {
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                if (oldItems.size() > 0) {
+                    Items newItems = new Items(oldItems);
+                    newItems.remove(newItems.size() - 1);
+                    newItems.add(new LoadingEndBean());
+                    adapter.setItems(newItems);
+                    adapter.notifyDataSetChanged();
+                } else if (oldItems.size() == 0) {
+                    oldItems.add(new LoadingEndBean());
+                    adapter.setItems(oldItems);
+                    adapter.notifyDataSetChanged();
+                }
+                canLoadMore = false;
+            }
+        });
+    }
+
+    @Override
+    public void onRefresh() {
+        int firstVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
+        if (firstVisibleItemPosition == 0) {
+            presenter.doRefresh();
+            return;
+        }
+        recyclerView.scrollToPosition(5);
+        recyclerView.smoothScrollToPosition(0);
+    }
+
+    @Override
+    public void onDestroy() {
+        RxBus.getInstance().unregister(BaseList2Fragment.TAG, observable);
+        super.onDestroy();
+    }
+}

+ 72 - 0
app/src/main/java/org/yczbj/ycvideoplayer/service/InitializeService.java

@@ -0,0 +1,72 @@
+package org.yczbj.ycvideoplayer.service;
+
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+
+import com.liulishuo.filedownloader.FileDownloader;
+import com.liulishuo.filedownloader.connection.FileDownloadUrlConnection;
+
+import org.yczbj.ycvideoplayer.base.BaseApplication;
+import org.yczbj.ycvideoplayer.base.BaseConfig;
+import org.yczbj.ycvideoplayer.util.LogUtils;
+
+import java.net.Proxy;
+
+public class InitializeService extends IntentService {
+
+    private static final String ACTION_INIT = "initApplication";
+
+    public static void start(Context context) {
+        Intent intent = new Intent(context, InitializeService.class);
+        intent.setAction(ACTION_INIT);
+        context.startService(intent);
+    }
+
+    /**
+     * Creates an IntentService.  Invoked by your subclass's constructor.
+     * Used to name the worker thread, important only for debugging.
+     */
+    /*public InitializeService(String name) {
+        super(name);
+    }*/
+
+    public InitializeService(){
+        super("InitializeService");
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        if (intent != null) {
+            final String action = intent.getAction();
+            if (ACTION_INIT.equals(action)) {
+                initApplication();
+            }
+        }
+    }
+
+    private void initApplication() {
+        BaseConfig.INSTANCE.initConfig();
+        LogUtils.logDebug = true;
+        initDownLoadLib();
+    }
+
+
+    /**
+     * 初始化下载库
+     */
+    private void initDownLoadLib() {
+        FileDownloader.setupOnApplicationOnCreate(BaseApplication.getInstance())
+                .connectionCreator(new FileDownloadUrlConnection
+                        .Creator(new FileDownloadUrlConnection.Configuration()
+                        .connectTimeout(15_000)
+                        .readTimeout(15_000)
+                        .proxy(Proxy.NO_PROXY)
+                ))
+                .commit();
+        //最简单的初始化
+        //FileDownloader.setup(instance);
+    }
+
+
+}

+ 7 - 0
app/src/main/java/org/yczbj/ycvideoplayer/test/test3/ui/activity/DLMyFileTestActivity.java

@@ -6,6 +6,7 @@ import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.TextView;
 
 import com.blankj.utilcode.util.ScreenUtils;
 import com.blankj.utilcode.util.SizeUtils;
@@ -34,6 +35,10 @@ public class DLMyFileTestActivity extends BaseActivity implements View.OnClickLi
     Button btn1;
     @Bind(R.id.btn_2)
     Button btn2;
+    @Bind(R.id.tv_1)
+    TextView tv1;
+    @Bind(R.id.tv_2)
+    TextView tv2;
     @Bind(R.id.video_player)
     VideoPlayer videoPlayer;
 
@@ -51,6 +56,8 @@ public class DLMyFileTestActivity extends BaseActivity implements View.OnClickLi
     public void initListener() {
         btn1.setOnClickListener(this);
         btn2.setOnClickListener(this);
+        tv1.setOnClickListener(this);
+        tv2.setOnClickListener(this);
     }
 
     @Override

+ 126 - 36
app/src/main/java/org/yczbj/ycvideoplayer/ui/home/view/fragment/HomeFragment.java

@@ -2,10 +2,16 @@ package org.yczbj.ycvideoplayer.ui.home.view.fragment;
 
 import android.content.Context;
 import android.graphics.Color;
+import android.os.Bundle;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 
 import com.alibaba.android.vlayout.DelegateAdapter;
 import com.alibaba.android.vlayout.VirtualLayoutManager;
@@ -18,21 +24,25 @@ import com.yc.cn.ycbaseadapterlib.first.BaseViewHolder;
 
 import org.yczbj.ycvideoplayer.R;
 import org.yczbj.ycvideoplayer.api.constant.Constant;
+import org.yczbj.ycvideoplayer.base.BaseConfig;
 import org.yczbj.ycvideoplayer.base.BaseDelegateAdapter;
 import org.yczbj.ycvideoplayer.base.mvp1.BaseFragment;
+import org.yczbj.ycvideoplayer.test.test1.TestActivity;
+import org.yczbj.ycvideoplayer.test.test2.TestMyActivity;
+import org.yczbj.ycvideoplayer.test.test3.ui.activity.GlideCropActivity;
 import org.yczbj.ycvideoplayer.ui.home.view.activity.VideoPlayerJzActivity;
 import org.yczbj.ycvideoplayer.ui.home.view.activity.VideoPlayerMeActivity;
 import org.yczbj.ycvideoplayer.ui.home.view.adapter.BannerPagerAdapter;
 import org.yczbj.ycvideoplayer.ui.main.view.activity.MainActivity;
-import org.yczbj.ycvideoplayer.test.test1.TestActivity;
-import org.yczbj.ycvideoplayer.test.test2.TestMyActivity;
-import org.yczbj.ycvideoplayer.test.test3.ui.activity.GlideCropActivity;
+import org.yczbj.ycvideoplayer.util.LogUtils;
+import org.yczbj.ycvideoplayer.util.animation.AnimationsUtils;
 
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
 import butterknife.Bind;
+import butterknife.ButterKnife;
 
 
 /**
@@ -44,13 +54,17 @@ import butterknife.Bind;
  * 修订历史:
  * ================================================
  */
-public class HomeFragment extends BaseFragment {
+public class HomeFragment extends BaseFragment implements View.OnClickListener {
 
 
     @Bind(R.id.recyclerView)
     RecyclerView recyclerView;
     @Bind(R.id.refresh)
     SwipeRefreshLayout refresh;
+    @Bind(R.id.ll_search)
+    LinearLayout llSearch;
+    @Bind(R.id.ll_bind)
+    LinearLayout llBind;
     private MainActivity activity;
     private BannerView mBanner;
     private VirtualLayoutManager layoutManager;
@@ -59,6 +73,7 @@ public class HomeFragment extends BaseFragment {
      * 存放各个模块的适配器
      */
     private List<DelegateAdapter.Adapter> mAdapters;
+    private DelegateAdapter delegateAdapter;
 
     @Override
     public void onAttach(Context context) {
@@ -76,7 +91,7 @@ public class HomeFragment extends BaseFragment {
     @Override
     public void onPause() {
         super.onPause();
-        if(mBanner!=null){
+        if (mBanner != null) {
             mBanner.pause();
         }
     }
@@ -84,20 +99,51 @@ public class HomeFragment extends BaseFragment {
     @Override
     public void onResume() {
         super.onResume();
-        if(mBanner!=null){
+        if (mBanner != null) {
             mBanner.resume();
         }
+        initOldUserBinding();
+    }
+
+    /**
+     * onHiddenChanged这个方法可以用来在切换Fragment的时候,进行一些即时的操作(如改变后要刷新、保存等)。
+     * @param hidden        是否隐藏
+     */
+    @Override
+    public void onHiddenChanged(boolean hidden) {
+        super.onHiddenChanged(hidden);
+        if(!hidden){
+            initOldUserBinding();
+        }
     }
 
 
     @Override
     public int getContentView() {
-        return R.layout.base_refresh_recycler_view;
+        return R.layout.fragment_home;
     }
 
 
     @Override
     public void initView() {
+        initOldUserBinding();
+        initVLayout();
+        initRefreshView();
+    }
+
+
+    private void initOldUserBinding() {
+        boolean login = BaseConfig.INSTANCE.getIsLogin();
+        if (login) {
+            llBind.setVisibility(View.GONE);
+        } else {
+            llBind.setVisibility(View.VISIBLE);
+        }
+        llBind.setVisibility(View.VISIBLE);
+    }
+
+
+    private void initVLayout() {
         mAdapters = new LinkedList<>();
         //初始化
         //创建VirtualLayoutManager对象
@@ -110,22 +156,21 @@ public class HomeFragment extends BaseFragment {
         viewPool.setMaxRecycledViews(0, 20);
 
         //设置适配器
-        DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, true);
+        delegateAdapter = new DelegateAdapter(layoutManager, true);
         recyclerView.setAdapter(delegateAdapter);
 
         //自定义各种不同适配器
         initAllTypeView();
         //设置适配器
         delegateAdapter.setAdapters(mAdapters);
-        initRefreshView();
     }
 
-
+    private boolean isTopShow = true;
     private void initRefreshView() {
         refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
             @Override
             public void onRefresh() {
-                if(refresh.isRefreshing()){
+                if (refresh.isRefreshing()) {
                     refresh.setRefreshing(false);
                 }
             }
@@ -134,12 +179,14 @@ public class HomeFragment extends BaseFragment {
             @Override
             public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                 super.onScrollStateChanged(recyclerView, newState);
-                if(refresh.isRefreshing()){
+                if (refresh.isRefreshing()) {
                     return;
                 }
                 if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-                    //加载更多
-                    ToastUtil.showToast(activity,"没有更多数据!!!!!");
+                    if (lastVisibleItem == delegateAdapter.getItemCount() -1 ){
+                        //加载更多
+                        ToastUtil.showToast(activity, "没有更多数据!!!!!");
+                    }
                 }
             }
 
@@ -147,6 +194,37 @@ public class HomeFragment extends BaseFragment {
             public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                 super.onScrolled(recyclerView, dx, dy);
                 lastVisibleItem = layoutManager.findLastVisibleItemPosition();
+                boolean isTopScroll = recyclerView.canScrollVertically(-1);
+                //判断是否滑到了顶部
+                if(!isTopScroll){
+                    isTopShow = true;
+                    llBind.animate().translationY(0);
+                    return;
+                }
+                float scaleY = recyclerView.getScaleY();
+                LogUtils.e("onScrolled"+scaleY+"---"+dy);
+                if(scaleY - dy > 0 && isTopShow) {
+                    //下移隐藏
+                    isTopShow = false;
+                    llBind.animate().translationY(-llBind.getHeight());
+                } else if(scaleY - dy < 0 && !isTopShow){
+                    //上移出现
+                    isTopShow = true;
+                    llBind.animate().translationY(0);
+                }
+                /*if(scaleY-dy>0 && isTopShow){
+                    isTopShow = false;
+                    Animation translateAnimation = AnimationsUtils
+                            .getTranslateAnimation(0,
+                                    0, -(float) llBind.getHeight(), 0, 500);
+                    llBind.setAnimation(translateAnimation);
+                }else if(scaleY-dy<0 && !isTopShow){
+                    isTopShow = true;
+                    Animation translateAnimation = AnimationsUtils
+                            .getTranslateAnimation(0,
+                                    0, 0, (float) llBind.getHeight(), 1000);
+                    llBind.setAnimation(translateAnimation);
+                }*/
             }
         });
     }
@@ -154,7 +232,8 @@ public class HomeFragment extends BaseFragment {
 
     @Override
     public void initListener() {
-
+        llSearch.setOnClickListener(this);
+        llBind.setOnClickListener(this);
     }
 
 
@@ -163,6 +242,19 @@ public class HomeFragment extends BaseFragment {
 
     }
 
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()){
+            case R.id.ll_search:
+
+                break;
+            case R.id.ll_bind:
+
+                break;
+            default:
+                break;
+        }
+    }
 
     /**
      * 添加不同类型数据布局
@@ -198,7 +290,7 @@ public class HomeFragment extends BaseFragment {
                 mBanner.setHintGravity(1);
                 mBanner.setAnimationDuration(1000);
                 mBanner.setPlayDelay(2000);
-                mBanner.setHintPadding(0,0,0, SizeUtil.dip2px(activity,10));
+                mBanner.setHintPadding(0, 0, 0, SizeUtil.dip2px(activity, 10));
                 mBanner.setAdapter(new BannerPagerAdapter(activity, arrayList));
 
             }
@@ -215,7 +307,7 @@ public class HomeFragment extends BaseFragment {
                 View.OnClickListener listener = new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        switch (v.getId()){
+                        switch (v.getId()) {
                             case R.id.tv_home_first:
                                 startActivity(TestActivity.class);
                                 break;
@@ -276,7 +368,6 @@ public class HomeFragment extends BaseFragment {
             @Override
             public void onBindViewHolder(BaseViewHolder holder, int position) {
                 super.onBindViewHolder(holder, position);
-
             }
         };
         mAdapters.add(adAdapter);
@@ -397,13 +488,12 @@ public class HomeFragment extends BaseFragment {
     }
 
 
-
     private void initTitleView(final int type) {
         BaseDelegateAdapter titleAdapter = new BaseDelegateAdapter(activity, new LinearLayoutHelper(), R.layout.view_vlayout_title, 1, Constant.viewType.typeTitle) {
             @Override
             public void onBindViewHolder(BaseViewHolder holder, int position) {
                 super.onBindViewHolder(holder, position);
-                switch (type){
+                switch (type) {
                     case 1:
                         holder.setText(R.id.tv_title, "为你精选");
                         break;
@@ -429,27 +519,27 @@ public class HomeFragment extends BaseFragment {
                 holder.getView(R.id.tv_change).setOnClickListener(new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        switch (type){
+                        switch (type) {
                             case 1:
-                                ToastUtil.showToast(activity,"刷新为你精选数据");
+                                ToastUtil.showToast(activity, "刷新为你精选数据");
                                 break;
                             case 2:
-                                ToastUtil.showToast(activity,"刷新推广专区数据");
+                                ToastUtil.showToast(activity, "刷新推广专区数据");
                                 break;
                             case 3:
-                                ToastUtil.showToast(activity,"刷新行业动态数据");
+                                ToastUtil.showToast(activity, "刷新行业动态数据");
                                 break;
                             case 4:
-                                ToastUtil.showToast(activity,"刷新趋势分析数据");
+                                ToastUtil.showToast(activity, "刷新趋势分析数据");
                                 break;
                             case 5:
-                                ToastUtil.showToast(activity,"刷新大牛分享数据");
+                                ToastUtil.showToast(activity, "刷新大牛分享数据");
                                 break;
                             case 6:
-                                ToastUtil.showToast(activity,"刷新潇湘剑雨的数据");
+                                ToastUtil.showToast(activity, "刷新潇湘剑雨的数据");
                                 break;
                             default:
-                                ToastUtil.showToast(activity,"刷新XXXX数据");
+                                ToastUtil.showToast(activity, "刷新XXXX数据");
                                 break;
                         }
                     }
@@ -465,7 +555,7 @@ public class HomeFragment extends BaseFragment {
             @Override
             public void onBindViewHolder(BaseViewHolder holder, int position) {
                 super.onBindViewHolder(holder, position);
-                switch (type){
+                switch (type) {
                     case 1:
                         holder.setText(R.id.tv_more, "查看更多");
                         break;
@@ -491,24 +581,24 @@ public class HomeFragment extends BaseFragment {
                 holder.getView(R.id.tv_more).setOnClickListener(new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        switch (type){
+                        switch (type) {
                             case 1:
-                                ToastUtil.showToast(activity,"跳转为你精选数据");
+                                ToastUtil.showToast(activity, "跳转为你精选数据");
                                 break;
                             case 2:
-                                ToastUtil.showToast(activity,"跳转推广专区数据");
+                                ToastUtil.showToast(activity, "跳转推广专区数据");
                                 break;
                             case 3:
-                                ToastUtil.showToast(activity,"跳转行业动态数据");
+                                ToastUtil.showToast(activity, "跳转行业动态数据");
                                 break;
                             case 4:
-                                ToastUtil.showToast(activity,"跳转趋势分析数据");
+                                ToastUtil.showToast(activity, "跳转趋势分析数据");
                                 break;
                             case 5:
-                                ToastUtil.showToast(activity,"跳转大牛分享数据");
+                                ToastUtil.showToast(activity, "跳转大牛分享数据");
                                 break;
                             default:
-                                ToastUtil.showToast(activity,"跳转XXXX数据");
+                                ToastUtil.showToast(activity, "跳转XXXX数据");
                                 break;
                         }
                     }

+ 43 - 2
app/src/main/java/org/yczbj/ycvideoplayer/ui/main/view/activity/MainActivity.java

@@ -16,10 +16,12 @@ import com.liulishuo.filedownloader.FileDownloader;
 import com.ns.yc.ycutilslib.managerLeak.InputMethodManagerLeakUtils;
 
 import org.yczbj.ycvideoplayer.R;
+import org.yczbj.ycvideoplayer.api.constant.Constant;
 import org.yczbj.ycvideoplayer.base.AppManager;
 import org.yczbj.ycvideoplayer.base.mvp1.BaseActivity;
 import org.yczbj.ycvideoplayer.base.BaseFragmentFactory;
 import org.yczbj.ycvideoplayer.download.TasksManager;
+import org.yczbj.ycvideoplayer.ui.news.NewsFragment;
 import org.yczbj.ycvideoplayer.ui.video.VideoFragment;
 import org.yczbj.ycvideoplayer.ui.home.view.fragment.HomeFragment;
 import org.yczbj.ycvideoplayer.ui.main.contract.MainContract;
@@ -54,15 +56,18 @@ public class MainActivity extends BaseActivity implements MainContract.View {
     private static final int FRAGMENT_SPECIAL = 1;
     private static final int FRAGMENT_VIDEO = 2;
     private static final int FRAGMENT_ME = 3;
+    private static final int FRAGMENT_NEWS = 4;
     private int position;
 
     private MainContract.Presenter presenter = new MainPresenter(this);
     private long exitTime;
+    private long firstClickTime = 0;
     private Bundle savedInstanceState;
     private HomeFragment homeFragment;
     private SpecialFragment specialFragment;
     private VideoFragment videoFragment;
     private MeFragment meFragment;
+    private NewsFragment newsFragment;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -85,6 +90,7 @@ public class MainActivity extends BaseActivity implements MainContract.View {
     protected void onSaveInstanceState(Bundle outState) {
         // recreate 时记录当前位置 (在 Manifest 已禁止 Activity 旋转,所以旋转屏幕并不会执行以下代码)
         // 程序意外崩溃时保存状态信息
+        super.onSaveInstanceState(outState);
         outState.putInt(POSITION, position);
         outState.putInt(SELECT_ITEM, ctlTable.getCurrentTab());
     }
@@ -133,12 +139,16 @@ public class MainActivity extends BaseActivity implements MainContract.View {
                         showFragment(FRAGMENT_HOME);
                         break;
                     case 1:
-                        showFragment(FRAGMENT_SPECIAL);
+                        showFragment(FRAGMENT_NEWS);
                         break;
                     case 2:
-                        showFragment(FRAGMENT_VIDEO);
+                        showFragment(FRAGMENT_SPECIAL);
                         break;
                     case 3:
+                        showFragment(FRAGMENT_VIDEO);
+                        doubleClick(FRAGMENT_VIDEO);
+                        break;
+                    case 4:
                         showFragment(FRAGMENT_ME);
                         break;
                     default:
@@ -158,6 +168,7 @@ public class MainActivity extends BaseActivity implements MainContract.View {
     private void initFragment() {
         if(savedInstanceState!=null){
             homeFragment = BaseFragmentFactory.getInstance().getHomeFragment();
+            newsFragment = BaseFragmentFactory.getInstance().getNewsFragment();
             specialFragment = BaseFragmentFactory.getInstance().getSpecialFragment();
             videoFragment = BaseFragmentFactory.getInstance().getVideoFragment();
             meFragment = BaseFragmentFactory.getInstance().getMeFragment();
@@ -211,6 +222,14 @@ public class MainActivity extends BaseActivity implements MainContract.View {
                     ft.show(meFragment);
                 }
                 break;
+            case FRAGMENT_NEWS:
+                if (newsFragment == null) {
+                    newsFragment = BaseFragmentFactory.getInstance().getNewsFragment();
+                    ft.add(R.id.fl_main, newsFragment, MeFragment.class.getName());
+                } else {
+                    ft.show(newsFragment);
+                }
+                break;
             default:
                 break;
         }
@@ -223,6 +242,9 @@ public class MainActivity extends BaseActivity implements MainContract.View {
         if (homeFragment != null) {
             setHide(ft,homeFragment);
         }
+        if (newsFragment != null) {
+            setHide(ft,newsFragment);
+        }
         if (specialFragment != null) {
             setHide(ft,specialFragment);
         }
@@ -241,6 +263,25 @@ public class MainActivity extends BaseActivity implements MainContract.View {
     }
 
 
+    private void doubleClick(int index) {
+        long secondClickTime = System.currentTimeMillis();
+        if ((secondClickTime - firstClickTime < Constant.CLICK_TIME)) {
+            switch (index) {
+                case FRAGMENT_NEWS:
+                    newsFragment.onDoubleClick();
+                    break;
+                case FRAGMENT_VIDEO:
+                    videoFragment.onDoubleClick();
+                    break;
+                default:
+                    break;
+            }
+        } else {
+            firstClickTime = secondClickTime;
+        }
+    }
+
+
     @Override
     public Activity getActivity() {
         return this;

+ 105 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/NewsFragment.java

@@ -0,0 +1,105 @@
+package org.yczbj.ycvideoplayer.ui.news;
+
+import android.content.Context;
+import android.support.design.widget.TabLayout;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.ViewPager;
+
+import com.blankj.utilcode.util.Utils;
+
+import org.yczbj.ycvideoplayer.R;
+import org.yczbj.ycvideoplayer.base.BasePagerAdapter;
+import org.yczbj.ycvideoplayer.base.mvp1.BaseLazyFragment;
+import org.yczbj.ycvideoplayer.base.mvp2.BaseList1Fragment;
+import org.yczbj.ycvideoplayer.ui.main.view.activity.MainActivity;
+import org.yczbj.ycvideoplayer.ui.news.view.fragment.NewsArticleFragment;
+import org.yczbj.ycvideoplayer.util.SettingUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.Bind;
+
+/**
+ * Created by yc on 2018/2/28.
+ */
+
+public class NewsFragment extends BaseLazyFragment {
+
+    @Bind(R.id.tab_layout)
+    TabLayout tabLayout;
+    @Bind(R.id.view_pager)
+    ViewPager viewPager;
+    private MainActivity activity;
+
+    private List<Fragment> fragmentList = new ArrayList<>();
+    private BasePagerAdapter adapter;
+    private String[] categoryId;
+    private String[] categoryName;
+
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        activity = (MainActivity) context;
+    }
+
+    @Override
+    public void onDetach() {
+        super.onDetach();
+        activity = null;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        tabLayout.setBackgroundColor(SettingUtil.getInstance().getColor());
+    }
+
+
+    @Override
+    public int getContentView() {
+        return R.layout.base_tab_view;
+    }
+
+    @Override
+    public void initView() {
+        tabLayout.setupWithViewPager(viewPager);
+        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
+        tabLayout.setBackgroundColor(SettingUtil.getInstance().getColor());
+        viewPager.setOffscreenPageLimit(10);
+    }
+
+    @Override
+    public void initListener() {
+
+    }
+
+    @Override
+    public void initData() {
+        categoryId = Utils.getContext().getResources().getStringArray(R.array.mobile_news_id);
+        categoryName = Utils.getContext().getResources().getStringArray(R.array.mobile_news_name);
+    }
+
+    @Override
+    public void onLazyLoad() {
+        ArrayList<String> title = new ArrayList<>();
+        if(categoryId.length<=15){
+            return;
+        }
+        for (int i = 0; i < 15; i++) {
+            Fragment fragment = NewsArticleFragment.newInstance(categoryId[i]);
+            fragmentList.add(fragment);
+            title.add(categoryName[i]);
+        }
+        adapter = new BasePagerAdapter(getChildFragmentManager(), fragmentList,title);
+        viewPager.setAdapter(adapter);
+    }
+
+    public void onDoubleClick() {
+        if (fragmentList != null && fragmentList.size() > 0) {
+            int item = viewPager.getCurrentItem();
+            ((BaseList1Fragment) fragmentList.get(item)).onRefresh();
+        }
+    }
+
+}

+ 48 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/contract/INewsArticle.java

@@ -0,0 +1,48 @@
+package org.yczbj.ycvideoplayer.ui.news.contract;
+
+
+
+import org.yczbj.ycvideoplayer.base.mvp2.IBaseListView;
+import org.yczbj.ycvideoplayer.base.mvp2.IBasePresenter;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleDataBean;
+
+import java.util.List;
+
+public interface INewsArticle {
+
+    interface View extends IBaseListView<Presenter> {
+
+        /**
+         * 请求数据
+         */
+        void onLoadData();
+
+        /**
+         * 刷新
+         */
+        void onRefresh();
+    }
+
+    interface Presenter extends IBasePresenter {
+
+        /**
+         * 请求数据
+         */
+        void doLoadData(String... category);
+
+        /**
+         * 再起请求数据
+         */
+        void doLoadMoreData();
+
+        /**
+         * 设置适配器
+         */
+        void doSetAdapter(List<MultiNewsArticleDataBean> dataBeen);
+
+        /**
+         * 加载完毕
+         */
+        void doShowNoMore();
+    }
+}

+ 448 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/model/bean/NewsCommentBean.java

@@ -0,0 +1,448 @@
+package org.yczbj.ycvideoplayer.ui.news.model.bean;
+
+import java.util.List;
+
+public class NewsCommentBean {
+
+    /**
+     * detail_no_comment : 0
+     * total_number : 59
+     * ban_comment : false
+     * has_more : true
+     * go_topic_detail : 1
+     * stick_total_number : 0
+     * tab_info : {"tabs":["热度","时间"],"current_tab_index":0}
+     * fold_comment_count : 0
+     * show_add_forum : 1
+     * stable : true
+     * stick_has_more : false
+     * message : success
+     */
+
+    private int detail_no_comment;
+    private int total_number;
+    private boolean ban_comment;
+    private boolean has_more;
+    private int go_topic_detail;
+    private int stick_total_number;
+    private TabInfoBean tab_info;
+    private int fold_comment_count;
+    private int show_add_forum;
+    private boolean stable;
+    private boolean stick_has_more;
+    private String message;
+    private List<DataBean> data;
+
+    public int getDetail_no_comment() {
+        return detail_no_comment;
+    }
+
+    public void setDetail_no_comment(int detail_no_comment) {
+        this.detail_no_comment = detail_no_comment;
+    }
+
+    public int getTotal_number() {
+        return total_number;
+    }
+
+    public void setTotal_number(int total_number) {
+        this.total_number = total_number;
+    }
+
+    public boolean isBan_comment() {
+        return ban_comment;
+    }
+
+    public void setBan_comment(boolean ban_comment) {
+        this.ban_comment = ban_comment;
+    }
+
+    public boolean isHas_more() {
+        return has_more;
+    }
+
+    public void setHas_more(boolean has_more) {
+        this.has_more = has_more;
+    }
+
+    public int getGo_topic_detail() {
+        return go_topic_detail;
+    }
+
+    public void setGo_topic_detail(int go_topic_detail) {
+        this.go_topic_detail = go_topic_detail;
+    }
+
+    public int getStick_total_number() {
+        return stick_total_number;
+    }
+
+    public void setStick_total_number(int stick_total_number) {
+        this.stick_total_number = stick_total_number;
+    }
+
+    public TabInfoBean getTab_info() {
+        return tab_info;
+    }
+
+    public void setTab_info(TabInfoBean tab_info) {
+        this.tab_info = tab_info;
+    }
+
+    public int getFold_comment_count() {
+        return fold_comment_count;
+    }
+
+    public void setFold_comment_count(int fold_comment_count) {
+        this.fold_comment_count = fold_comment_count;
+    }
+
+    public int getShow_add_forum() {
+        return show_add_forum;
+    }
+
+    public void setShow_add_forum(int show_add_forum) {
+        this.show_add_forum = show_add_forum;
+    }
+
+    public boolean isStable() {
+        return stable;
+    }
+
+    public void setStable(boolean stable) {
+        this.stable = stable;
+    }
+
+    public boolean isStick_has_more() {
+        return stick_has_more;
+    }
+
+    public void setStick_has_more(boolean stick_has_more) {
+        this.stick_has_more = stick_has_more;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public List<DataBean> getData() {
+        return data;
+    }
+
+    public void setData(List<DataBean> data) {
+        this.data = data;
+    }
+
+    public static class TabInfoBean {
+        /**
+         * tabs : ["热度","时间"]
+         * current_tab_index : 0
+         */
+
+        private int current_tab_index;
+        private List<String> tabs;
+
+        public int getCurrent_tab_index() {
+            return current_tab_index;
+        }
+
+        public void setCurrent_tab_index(int current_tab_index) {
+            this.current_tab_index = current_tab_index;
+        }
+
+        public List<String> getTabs() {
+            return tabs;
+        }
+
+        public void setTabs(List<String> tabs) {
+            this.tabs = tabs;
+        }
+    }
+
+    public static class DataBean {
+        /**
+         * comment : {"is_followed":0,"text":"我们的未来有希望了,","reply_count":0,"is_following":0,"reply_list":[],"user_verified":false,"is_blocking":0,"user_id":50022511998,"bury_count":0,"author_badge":[],"id":50029624449,"verified_reason":"","platform":"feifei","score":0,"user_name":"WolfRoad124180199","user_profile_image_url":"http://p1.pstatp.com/thumb/729001d88c6944f970b","user_bury":0,"user_digg":0,"is_blocked":0,"user_relation":0,"user_auth_info":"","digg_count":33,"create_time":1470145059}
+         * cell_type : 1
+         */
+
+        private CommentBean comment;
+        private int cell_type;
+
+        public CommentBean getComment() {
+            return comment;
+        }
+
+        public void setComment(CommentBean comment) {
+            this.comment = comment;
+        }
+
+        public int getCell_type() {
+            return cell_type;
+        }
+
+        public void setCell_type(int cell_type) {
+            this.cell_type = cell_type;
+        }
+
+        public static class CommentBean {
+            /**
+             * is_followed : 0
+             * text : 我们的未来有希望了,
+             * reply_count : 0
+             * is_following : 0
+             * reply_list : []
+             * user_verified : false
+             * is_blocking : 0
+             * user_id : 50022511998
+             * bury_count : 0
+             * author_badge : []
+             * id : 50029624449
+             * verified_reason :
+             * platform : feifei
+             * score : 0
+             * user_name : WolfRoad124180199
+             * user_profile_image_url : http://p1.pstatp.com/thumb/729001d88c6944f970b
+             * user_bury : 0
+             * user_digg : 0
+             * is_blocked : 0
+             * user_relation : 0
+             * user_auth_info :
+             * digg_count : 33
+             * create_time : 1470145059
+             */
+
+            private int is_followed;
+            private String text;
+            private int reply_count;
+            private int is_following;
+            private boolean user_verified;
+            private int is_blocking;
+            private long user_id;
+            private int bury_count;
+            private long id;
+            private String verified_reason;
+            private String platform;
+            //            private long score;
+            private String user_name;
+            private String user_profile_image_url;
+            private int user_bury;
+            private int user_digg;
+            private int is_blocked;
+            private int user_relation;
+            private String user_auth_info;
+            private int digg_count;
+            private int create_time;
+            private List<?> reply_list;
+            private List<?> author_badge;
+
+            @Override
+            public boolean equals(Object o) {
+                if (this == o)
+                    return true;
+                if (o == null || getClass() != o.getClass())
+                    return false;
+
+                CommentBean that = (CommentBean) o;
+
+                if (create_time != that.create_time)
+                    return false;
+                return text.equals(that.text);
+            }
+
+            @Override
+            public int hashCode() {
+                int result = text.hashCode();
+                result = 31 * result + create_time;
+                return result;
+            }
+
+            public int getIs_followed() {
+                return is_followed;
+            }
+
+            public void setIs_followed(int is_followed) {
+                this.is_followed = is_followed;
+            }
+
+            public String getText() {
+                return text;
+            }
+
+            public void setText(String text) {
+                this.text = text;
+            }
+
+            public int getReply_count() {
+                return reply_count;
+            }
+
+            public void setReply_count(int reply_count) {
+                this.reply_count = reply_count;
+            }
+
+            public int getIs_following() {
+                return is_following;
+            }
+
+            public void setIs_following(int is_following) {
+                this.is_following = is_following;
+            }
+
+            public boolean isUser_verified() {
+                return user_verified;
+            }
+
+            public void setUser_verified(boolean user_verified) {
+                this.user_verified = user_verified;
+            }
+
+            public int getIs_blocking() {
+                return is_blocking;
+            }
+
+            public void setIs_blocking(int is_blocking) {
+                this.is_blocking = is_blocking;
+            }
+
+            public long getUser_id() {
+                return user_id;
+            }
+
+            public void setUser_id(long user_id) {
+                this.user_id = user_id;
+            }
+
+            public int getBury_count() {
+                return bury_count;
+            }
+
+            public void setBury_count(int bury_count) {
+                this.bury_count = bury_count;
+            }
+
+            public long getId() {
+                return id;
+            }
+
+            public void setId(long id) {
+                this.id = id;
+            }
+
+            public String getVerified_reason() {
+                return verified_reason;
+            }
+
+            public void setVerified_reason(String verified_reason) {
+                this.verified_reason = verified_reason;
+            }
+
+            public String getPlatform() {
+                return platform;
+            }
+
+            public void setPlatform(String platform) {
+                this.platform = platform;
+            }
+
+//            public long getScore() {
+//                return score;
+//            }
+
+//            public void setScore(int score) {
+//                this.score = score;
+//            }
+
+            public String getUser_name() {
+                return user_name;
+            }
+
+            public void setUser_name(String user_name) {
+                this.user_name = user_name;
+            }
+
+            public String getUser_profile_image_url() {
+                return user_profile_image_url;
+            }
+
+            public void setUser_profile_image_url(String user_profile_image_url) {
+                this.user_profile_image_url = user_profile_image_url;
+            }
+
+            public int getUser_bury() {
+                return user_bury;
+            }
+
+            public void setUser_bury(int user_bury) {
+                this.user_bury = user_bury;
+            }
+
+            public int getUser_digg() {
+                return user_digg;
+            }
+
+            public void setUser_digg(int user_digg) {
+                this.user_digg = user_digg;
+            }
+
+            public int getIs_blocked() {
+                return is_blocked;
+            }
+
+            public void setIs_blocked(int is_blocked) {
+                this.is_blocked = is_blocked;
+            }
+
+            public int getUser_relation() {
+                return user_relation;
+            }
+
+            public void setUser_relation(int user_relation) {
+                this.user_relation = user_relation;
+            }
+
+            public String getUser_auth_info() {
+                return user_auth_info;
+            }
+
+            public void setUser_auth_info(String user_auth_info) {
+                this.user_auth_info = user_auth_info;
+            }
+
+            public int getDigg_count() {
+                return digg_count;
+            }
+
+            public void setDigg_count(int digg_count) {
+                this.digg_count = digg_count;
+            }
+
+            public int getCreate_time() {
+                return create_time;
+            }
+
+            public void setCreate_time(int create_time) {
+                this.create_time = create_time;
+            }
+
+            public List<?> getReply_list() {
+                return reply_list;
+            }
+
+            public void setReply_list(List<?> reply_list) {
+                this.reply_list = reply_list;
+            }
+
+            public List<?> getAuthor_badge() {
+                return author_badge;
+            }
+
+            public void setAuthor_badge(List<?> author_badge) {
+                this.author_badge = author_badge;
+            }
+        }
+    }
+}

+ 129 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/model/binder/NewsArticleImgViewBinder.java

@@ -0,0 +1,129 @@
+package org.yczbj.ycvideoplayer.ui.news.model.binder;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.v7.widget.PopupMenu;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.blankj.utilcode.util.TimeUtils;
+import com.jakewharton.rxbinding2.view.RxView;
+
+import org.yczbj.ycvideoplayer.R;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleDataBean;
+import org.yczbj.ycvideoplayer.util.ImageUtil;
+import org.yczbj.ycvideoplayer.util.SettingUtil;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import io.reactivex.functions.Consumer;
+import me.drakeet.multitype.ItemViewBinder;
+
+/**
+ * 带图片的 item
+ */
+
+public class NewsArticleImgViewBinder extends ItemViewBinder<MultiNewsArticleDataBean, NewsArticleImgViewBinder.ViewHolder> {
+
+    @NonNull
+    @Override
+    protected ViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
+        View view = inflater.inflate(R.layout.item_news_article_img, parent, false);
+        return new ViewHolder(view);
+    }
+
+    @SuppressLint("SetTextI18n")
+    @Override
+    protected void onBindViewHolder(@NonNull final ViewHolder holder, @NonNull final MultiNewsArticleDataBean item) {
+
+        final Context context = holder.itemView.getContext();
+
+        try {
+            String imgUrl = "http://p3.pstatp.com/";
+            List<MultiNewsArticleDataBean.ImageListBean> image_list = item.getImage_list();
+            if (image_list != null && image_list.size() != 0) {
+                String url = image_list.get(0).getUrl();
+                ImageUtil.loadImgByPicasso(context,url,R.drawable.image_default,holder.ivImage);
+                if (!TextUtils.isEmpty(image_list.get(0).getUri())) {
+                    imgUrl += image_list.get(0).getUri().replace("list", "large");
+                }
+            }
+
+            if (null != item.getUser_info()) {
+                String avatar_url = item.getUser_info().getAvatar_url();
+                if (!TextUtils.isEmpty(avatar_url)) {
+                    ImageUtil.loadImgByPicasso(context,avatar_url,R.drawable.image_default,holder.ivMedia);
+                }
+            }
+
+            String tv_title = item.getTitle();
+            String tv_abstract = item.getAbstractX();
+            String tv_source = item.getSource();
+            String tv_comment_count = item.getComment_count() + "评论";
+            String tv_datetime = item.getBehot_time() + "";
+            if (!TextUtils.isEmpty(tv_datetime)) {
+                tv_datetime = TimeUtils.getFriendlyTimeSpanByNow(tv_datetime);
+            }
+
+            holder.tvTitle.setText(tv_title);
+            holder.tvTitle.setTextSize(SettingUtil.getInstance().getTextSize());
+            holder.tvAbstract.setText(tv_abstract);
+            holder.tvExtra.setText(tv_source + " - " + tv_comment_count + " - " + tv_datetime);
+            holder.ivDots.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+
+                }
+            });
+
+            final String finalImgUrl = imgUrl;
+            RxView.clicks(holder.itemView)
+                    .throttleFirst(1, TimeUnit.SECONDS)
+                    .subscribe(new Consumer<Object>() {
+                        @Override
+                        public void accept(@io.reactivex.annotations.NonNull Object o) throws Exception {
+                            //NewsContentActivity.launch(item, finalImgUrl);
+                        }
+                    });
+        } catch (Exception e) {
+
+        }
+    }
+
+    public class ViewHolder extends RecyclerView.ViewHolder {
+
+        @Bind(R.id.iv_media)
+        ImageView ivMedia;
+        @Bind(R.id.tv_extra)
+        TextView tvExtra;
+        @Bind(R.id.iv_dots)
+        ImageView ivDots;
+        @Bind(R.id.header)
+        LinearLayout header;
+        @Bind(R.id.tv_title)
+        TextView tvTitle;
+        @Bind(R.id.tv_abstract)
+        TextView tvAbstract;
+        @Bind(R.id.iv_image)
+        ImageView ivImage;
+        @Bind(R.id.ll_content)
+        LinearLayout llContent;
+
+        ViewHolder(View itemView) {
+            super(itemView);
+            ButterKnife.bind(this, itemView);
+        }
+    }
+}

+ 114 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/model/binder/NewsArticleTextViewBinder.java

@@ -0,0 +1,114 @@
+package org.yczbj.ycvideoplayer.ui.news.model.binder;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.v7.widget.PopupMenu;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.blankj.utilcode.util.TimeUtils;
+import com.jakewharton.rxbinding2.view.RxView;
+
+import org.yczbj.ycvideoplayer.R;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleDataBean;
+import org.yczbj.ycvideoplayer.util.ImageUtil;
+import org.yczbj.ycvideoplayer.util.SettingUtil;
+
+import java.util.concurrent.TimeUnit;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import io.reactivex.functions.Consumer;
+import me.drakeet.multitype.ItemViewBinder;
+
+/**
+ * 不带图片的 item
+ */
+
+public class NewsArticleTextViewBinder extends ItemViewBinder<MultiNewsArticleDataBean, NewsArticleTextViewBinder.ViewHolder> {
+
+    private static final String TAG = "NewsArticleTextViewBind";
+
+    @NonNull
+    @Override
+    protected ViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
+        View view = inflater.inflate(R.layout.item_news_article_text, parent, false);
+        return new ViewHolder(view);
+    }
+
+    @Override
+    protected void onBindViewHolder(@NonNull final ViewHolder holder, @NonNull final MultiNewsArticleDataBean item) {
+
+        final Context context = holder.itemView.getContext();
+
+        try {
+            if (null != item.getUser_info()) {
+                String avatar_url = item.getUser_info().getAvatar_url();
+                if (!TextUtils.isEmpty(avatar_url)) {
+                    ImageUtil.loadImgByPicasso(context,avatar_url,R.drawable.image_default,holder.ivMedia);
+                }
+            }
+
+            String tv_title = item.getTitle();
+            String tv_abstract = item.getAbstractX();
+            String tv_source = item.getSource();
+            String tv_comment_count = item.getComment_count() + "评论";
+            String tv_datetime = item.getBehot_time() + "";
+            if (!TextUtils.isEmpty(tv_datetime)) {
+                tv_datetime =  TimeUtils.getFriendlyTimeSpanByNow(tv_datetime);
+            }
+
+            holder.tvTitle.setText(tv_title);
+            holder.tvTitle.setTextSize(SettingUtil.getInstance().getTextSize());
+            holder.tvAbstract.setText(tv_abstract);
+            holder.tvExtra.setText(tv_source + " - " + tv_comment_count + " - " + tv_datetime);
+            holder.ivDots.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View view) {
+
+                }
+            });
+
+            RxView.clicks(holder.itemView)
+                    .throttleFirst(1, TimeUnit.SECONDS)
+                    .subscribe(new Consumer<Object>() {
+                        @Override
+                        public void accept(@io.reactivex.annotations.NonNull Object o) throws Exception {
+                            //NewsContentActivity.launch(item);
+                        }
+                    });
+        } catch (Exception e) {
+
+        }
+    }
+
+    class ViewHolder extends RecyclerView.ViewHolder {
+
+        @Bind(R.id.iv_media)
+        ImageView ivMedia;
+        @Bind(R.id.tv_extra)
+        TextView tvExtra;
+        @Bind(R.id.iv_dots)
+        ImageView ivDots;
+        @Bind(R.id.header)
+        LinearLayout header;
+        @Bind(R.id.tv_title)
+        TextView tvTitle;
+        @Bind(R.id.tv_abstract)
+        TextView tvAbstract;
+        @Bind(R.id.content)
+        LinearLayout content;
+        ViewHolder(View itemView) {
+            super(itemView);
+            ButterKnife.bind(this, itemView);
+        }
+    }
+}

+ 181 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/presenter/NewsArticlePresenter.java

@@ -0,0 +1,181 @@
+package org.yczbj.ycvideoplayer.ui.news.presenter;
+
+import android.text.TextUtils;
+
+import com.blankj.utilcode.util.TimeUtils;
+import com.google.gson.Gson;
+
+import org.yczbj.ycvideoplayer.api.http.news.NewsModel;
+import org.yczbj.ycvideoplayer.ui.news.contract.INewsArticle;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleBean;
+import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleDataBean;
+import org.yczbj.ycvideoplayer.util.LogUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.annotations.NonNull;
+import io.reactivex.functions.Consumer;
+import io.reactivex.functions.Function;
+import io.reactivex.functions.Predicate;
+import io.reactivex.schedulers.Schedulers;
+
+
+public class NewsArticlePresenter implements INewsArticle.Presenter {
+
+    private static final String TAG = "NewsArticlePresenter";
+    private INewsArticle.View view;
+    private List<MultiNewsArticleDataBean> dataList = new ArrayList<>();
+    private String category;
+    private String time;
+    private Gson gson = new Gson();
+    private Random random = new Random();
+
+    public NewsArticlePresenter(INewsArticle.View view) {
+        this.view = view;
+        this.time = TimeUtils.getNowString();
+    }
+
+    @Override
+    public void doLoadData(String... category) {
+
+        try {
+            if (this.category == null) {
+                this.category = category[0];
+            }
+        } catch (Exception e) {
+            LogUtils.e(e.getLocalizedMessage());
+        }
+
+        // 释放内存
+        if (dataList.size() > 150) {
+            dataList.clear();
+        }
+
+        getRandom()
+                .subscribeOn(Schedulers.io())
+                .switchMap(new Function<MultiNewsArticleBean, Observable<MultiNewsArticleDataBean>>() {
+                    @Override
+                    public Observable<MultiNewsArticleDataBean> apply(@NonNull MultiNewsArticleBean multiNewsArticleBean) throws Exception {
+                        List<MultiNewsArticleDataBean> dataList = new ArrayList<>();
+                        for (MultiNewsArticleBean.DataBean dataBean : multiNewsArticleBean.getData()) {
+                            dataList.add(gson.fromJson(dataBean.getContent(), MultiNewsArticleDataBean.class));
+                        }
+                        return Observable.fromIterable(dataList);
+                    }
+                })
+                .filter(new Predicate<MultiNewsArticleDataBean>() {
+                    @Override
+                    public boolean test(@NonNull MultiNewsArticleDataBean dataBean) throws Exception {
+                        time = dataBean.getBehot_time();
+                        if (TextUtils.isEmpty(dataBean.getSource())) {
+                            return false;
+                        }
+                        try {
+                            // 过滤头条问答新闻
+                            if (dataBean.getSource().contains("头条问答")
+                                    || dataBean.getTag().contains("ad")
+                                    || dataBean.getSource().contains("悟空问答")) {
+                                return false;
+                            }
+                            // 过滤头条问答新闻
+                            if (dataBean.getRead_count() == 0 || TextUtils.isEmpty(dataBean.getMedia_name())) {
+                                String title = dataBean.getTitle();
+                                if (title.lastIndexOf("?") == title.length() - 1) {
+                                    return false;
+                                }
+                            }
+                        } catch (NullPointerException e) {
+                            LogUtils.e(e.getLocalizedMessage());
+                        }
+                        // 过滤重复新闻(与上次刷新的数据比较)
+                        for (MultiNewsArticleDataBean bean : dataList) {
+                            if (bean.getTitle().equals(dataBean.getTitle())) {
+                                return false;
+                            }
+                        }
+                        return true;
+                    }
+                })
+                .toList()
+                .map(new Function<List<MultiNewsArticleDataBean>, List<MultiNewsArticleDataBean>>() {
+                    @Override
+                    public List<MultiNewsArticleDataBean> apply(@NonNull List<MultiNewsArticleDataBean> list) throws Exception {
+                        // 过滤重复新闻(与本次刷新的数据比较,因为使用了2个请求,数据会有重复)
+                        for (int i = 0; i < list.size() - 1; i++) {
+                            for (int j = list.size() - 1; j > i; j--) {
+                                if (list.get(j).getTitle().equals(list.get(i).getTitle())) {
+                                    list.remove(j);
+                                }
+                            }
+                        }
+                        return list;
+                    }
+                })
+                .compose(view.<List<MultiNewsArticleDataBean>>bindToLife())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Consumer<List<MultiNewsArticleDataBean>>() {
+                    @Override
+                    public void accept(@NonNull List<MultiNewsArticleDataBean> list) throws Exception {
+                        if (null != list && list.size() > 0) {
+                            doSetAdapter(list);
+                        } else {
+                            doShowNoMore();
+                        }
+                    }
+                }, new Consumer<Throwable>() {
+                    @Override
+                    public void accept(@NonNull Throwable throwable) throws Exception {
+                        doShowNetError();
+                        LogUtils.e(throwable.getLocalizedMessage());
+                    }
+                });
+    }
+
+    @Override
+    public void doLoadMoreData() {
+        doLoadData();
+    }
+
+    @Override
+    public void doSetAdapter(List<MultiNewsArticleDataBean> list) {
+        dataList.addAll(list);
+        view.onSetAdapter(dataList);
+        view.onHideLoading();
+    }
+
+    @Override
+    public void doRefresh() {
+        if (dataList.size() != 0) {
+            dataList.clear();
+            time = TimeUtils.getNowString();
+        }
+        view.onShowLoading();
+        doLoadData();
+    }
+
+    @Override
+    public void doShowNetError() {
+        view.onHideLoading();
+        view.onShowNetError();
+    }
+
+    @Override
+    public void doShowNoMore() {
+        view.onHideLoading();
+        view.onShowNoMore();
+    }
+
+    private Observable<MultiNewsArticleBean> getRandom() {
+        int i = random.nextInt(10);
+        NewsModel model = NewsModel.getInstance();
+        if (i % 2 == 0) {
+            return model.getNewsArticle(this.category, this.time);
+        } else {
+            return model.getNewsArticle2(this.category, this.time);
+        }
+    }
+}

+ 43 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/view/adapter/NewsArticleAdapter.java

@@ -0,0 +1,43 @@
+package org.yczbj.ycvideoplayer.ui.news.view.adapter;
+
+import android.app.Activity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.yczbj.ycrefreshviewlib.adapter.RecyclerArrayAdapter;
+import org.yczbj.ycrefreshviewlib.viewHolder.BaseViewHolder;
+import org.yczbj.ycvideoplayer.R;
+import org.yczbj.ycvideoplayer.ui.home.model.VideoPlayerComment;
+
+
+public class NewsArticleAdapter extends RecyclerArrayAdapter<VideoPlayerComment> {
+
+    public NewsArticleAdapter(Activity activity) {
+        super(activity);
+    }
+
+    @Override
+    public BaseViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) {
+        return new VideoPlayerViewHolder(parent);
+    }
+
+
+    private class VideoPlayerViewHolder extends BaseViewHolder<VideoPlayerComment> {
+
+        ImageView iv_movie_photo;
+        TextView tv_movie_title , tv_movie_directors ,tv_movie_casts,tv_movie_genres ,tv_movie_rating_rate;
+        View view_color;
+
+        VideoPlayerViewHolder(ViewGroup parent) {
+            super(parent, R.layout.item_video_player_com);
+        }
+
+        @Override
+        public void setData(VideoPlayerComment data) {
+            super.setData(data);
+
+        }
+    }
+}

+ 97 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/news/view/fragment/NewsArticleFragment.java

@@ -0,0 +1,97 @@
+package org.yczbj.ycvideoplayer.ui.news.view.fragment;
+
+import android.os.Bundle;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.View;
+
+import org.yczbj.ycvideoplayer.base.mvp2.BaseList1Fragment;
+import org.yczbj.ycvideoplayer.listener.OnLoadMoreListener;
+import org.yczbj.ycvideoplayer.model.LoadingBean;
+import org.yczbj.ycvideoplayer.ui.news.contract.INewsArticle;
+import org.yczbj.ycvideoplayer.ui.news.presenter.NewsArticlePresenter;
+import org.yczbj.ycvideoplayer.util.DiffCallback;
+import org.yczbj.ycvideoplayer.util.Register;
+
+import java.util.List;
+
+import me.drakeet.multitype.Items;
+import me.drakeet.multitype.MultiTypeAdapter;
+
+
+public class NewsArticleFragment extends BaseList1Fragment<INewsArticle.Presenter> implements INewsArticle.View, SwipeRefreshLayout.OnRefreshListener {
+
+    private static final String TAG = "NewsArticleFragment";
+    private String categoryId;
+
+    public static NewsArticleFragment newInstance(String categoryId) {
+        Bundle bundle = new Bundle();
+        bundle.putString(TAG, categoryId);
+        NewsArticleFragment newsArticleView = new NewsArticleFragment();
+        newsArticleView.setArguments(bundle);
+        return newsArticleView;
+    }
+
+    @Override
+    protected void initData() {
+        categoryId = getArguments().getString(TAG);
+    }
+
+    @Override
+    protected void initView(View view) {
+        super.initView(view);
+        adapter = new MultiTypeAdapter(oldItems);
+        Register.registerNewsArticleItem(adapter);
+        recyclerView.setAdapter(adapter);
+
+        recyclerView.addOnScrollListener(new OnLoadMoreListener() {
+            @Override
+            public void onLoadMore() {
+                if (canLoadMore) {
+                    canLoadMore = false;
+                    presenter.doLoadMoreData();
+                }
+            }
+        });
+    }
+
+    /**
+     * 懒加载调用请求数据接口
+     */
+    @Override
+    public void fetchData() {
+        super.fetchData();
+        onLoadData();
+    }
+
+
+    @Override
+    public void onLoadData() {
+        onShowLoading();
+        presenter.doLoadData(categoryId);
+    }
+
+
+    @Override
+    public void onSetAdapter(final List<?> list) {
+        Items newItems = new Items(list);
+        newItems.add(new LoadingBean());
+        DiffCallback.create(oldItems, newItems, adapter);
+        oldItems.clear();
+        oldItems.addAll(newItems);
+        canLoadMore = true;
+        recyclerView.stopScroll();
+    }
+
+
+    /**
+     * 设置presenter
+     * @param presenter         presenter
+     */
+    @Override
+    public void setPresenter(INewsArticle.Presenter presenter) {
+        if (null == presenter) {
+            this.presenter = new NewsArticlePresenter(this);
+        }
+    }
+
+}

+ 1 - 13
app/src/main/java/org/yczbj/ycvideoplayer/ui/person/MeFragment.java

@@ -17,11 +17,6 @@ import butterknife.Bind;
 
 public class MeFragment extends BaseFragment implements View.OnClickListener {
 
-    @Bind(R.id.tv_1)
-    TextView tv1;
-    @Bind(R.id.tv_2)
-    TextView tv2;
-
     @Override
     public int getContentView() {
         return R.layout.fragment_me;
@@ -34,8 +29,7 @@ public class MeFragment extends BaseFragment implements View.OnClickListener {
 
     @Override
     public void initListener() {
-        tv1.setOnClickListener(this);
-        tv2.setOnClickListener(this);
+
     }
 
     @Override
@@ -46,12 +40,6 @@ public class MeFragment extends BaseFragment implements View.OnClickListener {
     @Override
     public void onClick(View v) {
         switch (v.getId()){
-            case R.id.tv_1:
-
-                break;
-            case R.id.tv_2:
-
-                break;
             default:
                 break;
         }

+ 0 - 1
app/src/main/java/org/yczbj/ycvideoplayer/ui/special/SpecialFragment.java

@@ -54,7 +54,6 @@ import butterknife.Bind;
  * CreatedTime:2017/12/29
  * Author:yc
  */
-
 public class SpecialFragment extends BaseFragment implements SpecialContract.View {
 
 

+ 2 - 2
app/src/main/java/org/yczbj/ycvideoplayer/ui/video/VideoFragment.java

@@ -9,7 +9,7 @@ import com.blankj.utilcode.util.Utils;
 import org.yczbj.ycvideoplayer.R;
 import org.yczbj.ycvideoplayer.base.BasePagerAdapter;
 import org.yczbj.ycvideoplayer.base.mvp1.BaseFragment;
-import org.yczbj.ycvideoplayer.base.mvp2.BaseListFragment;
+import org.yczbj.ycvideoplayer.base.mvp2.BaseList1Fragment;
 import org.yczbj.ycvideoplayer.ui.video.view.fragment.VideoArticleFragment;
 import org.yczbj.ycvideoplayer.util.SettingUtil;
 
@@ -76,7 +76,7 @@ public class VideoFragment extends BaseFragment {
     public void onDoubleClick() {
         if (fragmentList != null && fragmentList.size() > 0) {
             int item = viewPager.getCurrentItem();
-            ((BaseListFragment) fragmentList.get(item)).onRefresh();
+            ((BaseList1Fragment) fragmentList.get(item)).onRefresh();
         }
     }
 

+ 2 - 2
app/src/main/java/org/yczbj/ycvideoplayer/ui/video/view/fragment/VideoArticleFragment.java

@@ -5,7 +5,7 @@ import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.View;
 
 
-import org.yczbj.ycvideoplayer.base.mvp2.BaseListFragment;
+import org.yczbj.ycvideoplayer.base.mvp2.BaseList1Fragment;
 import org.yczbj.ycvideoplayer.listener.OnLoadMoreListener;
 import org.yczbj.ycvideoplayer.model.LoadingBean;
 import org.yczbj.ycvideoplayer.ui.video.contract.IVideoArticle;
@@ -19,7 +19,7 @@ import me.drakeet.multitype.Items;
 import me.drakeet.multitype.MultiTypeAdapter;
 
 
-public class VideoArticleFragment extends BaseListFragment<IVideoArticle.Presenter> implements IVideoArticle.View, SwipeRefreshLayout.OnRefreshListener {
+public class VideoArticleFragment extends BaseList1Fragment<IVideoArticle.Presenter> implements IVideoArticle.View, SwipeRefreshLayout.OnRefreshListener {
 
     private static final String TAG = "VideoArticleView";
     private String categoryId;

+ 25 - 0
app/src/main/java/org/yczbj/ycvideoplayer/util/Register.java

@@ -6,9 +6,13 @@ import org.yczbj.ycvideoplayer.model.LoadingBean;
 import org.yczbj.ycvideoplayer.model.LoadingEndBean;
 import org.yczbj.ycvideoplayer.model.binder.LoadingEndViewBinder;
 import org.yczbj.ycvideoplayer.model.binder.LoadingViewBinder;
+import org.yczbj.ycvideoplayer.ui.news.model.binder.NewsArticleImgViewBinder;
+import org.yczbj.ycvideoplayer.ui.news.model.binder.NewsArticleTextViewBinder;
 import org.yczbj.ycvideoplayer.ui.video.model.bean.MultiNewsArticleDataBean;
 import org.yczbj.ycvideoplayer.ui.video.model.binder.NewsArticleVideoViewBinder;
 
+import me.drakeet.multitype.ClassLinker;
+import me.drakeet.multitype.ItemViewBinder;
 import me.drakeet.multitype.MultiTypeAdapter;
 
 /**
@@ -23,4 +27,25 @@ public class Register {
         adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
     }
 
+    public static void registerNewsArticleItem(MultiTypeAdapter adapter) {
+        adapter.register(MultiNewsArticleDataBean.class)
+                .to(new NewsArticleImgViewBinder(),
+                        new NewsArticleVideoViewBinder(),
+                        new NewsArticleTextViewBinder())
+                .withClassLinker(new ClassLinker<MultiNewsArticleDataBean>() {
+                    @NonNull
+                    @Override
+                    public Class<? extends ItemViewBinder<MultiNewsArticleDataBean, ?>> index(int position, @NonNull MultiNewsArticleDataBean item) {
+                        if (item.isHas_video()) {
+                            return NewsArticleVideoViewBinder.class;
+                        }
+                        if (null != item.getImage_list() && item.getImage_list().size() > 0) {
+                            return NewsArticleImgViewBinder.class;
+                        }
+                        return NewsArticleTextViewBinder.class;
+                    }
+                });
+        adapter.register(LoadingBean.class, new LoadingViewBinder());
+        adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
+    }
 }

+ 117 - 0
app/src/main/java/org/yczbj/ycvideoplayer/util/animation/AnimationViewUtil.java

@@ -0,0 +1,117 @@
+package org.yczbj.ycvideoplayer.util.animation;
+
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewAnimationUtils;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+public class AnimationViewUtil {
+
+    private static final long PERFECT_MILLS = 618;
+
+
+    public static void startActivity(Activity thisActivity, Intent intent,
+                                     View triggerView, int colorOrImageRes) {
+        startActivity(thisActivity, intent, triggerView, colorOrImageRes, PERFECT_MILLS);
+    }
+
+    public static void startActivity(Activity thisActivity, Intent intent,
+                                     View triggerView, int colorOrImageRes, long durationMills) {
+        startActivityForResult(thisActivity, intent, null, null,
+                triggerView, colorOrImageRes, durationMills);
+    }
+
+
+    /**
+     * 从指定View开始向四周伸张(伸张颜色或图片为colorOrImageRes), 然后进入另一个Activity,
+     * 返回至 @thisActivity 后显示收缩动画。
+     */
+    @SuppressLint("NewApi")
+    public static void startActivityForResult(final Activity thisActivity, final Intent intent,
+                                              final Integer requestCode, final Bundle bundle,
+                                              final View triggerView, int colorOrImageRes,
+                                              long durationMills) {
+        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+            thisActivity.startActivity(intent);
+            return;
+        }
+
+        int[] location = new int[2];
+        triggerView.getLocationInWindow(location);
+        final int cx = location[0] + triggerView.getWidth() / 2;
+        final int cy = location[1] + triggerView.getHeight() / 2;
+        final ImageView view = new ImageView(thisActivity);
+        view.setScaleType(ImageView.ScaleType.CENTER_CROP);
+        view.setImageResource(colorOrImageRes);
+        final ViewGroup decorView = (ViewGroup) thisActivity.getWindow().getDecorView();
+        int w = decorView.getWidth();
+        int h = decorView.getHeight();
+        decorView.addView(view, w, h);
+
+        // 计算中心点至view边界的最大距离
+        int maxW = Math.max(cx, w - cx);
+        int maxH = Math.max(cy, h - cy);
+        final int finalRadius = (int) Math.sqrt(maxW * maxW + maxH * maxH) + 1;
+        Animator
+                anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, 0, finalRadius);
+        int maxRadius = (int) Math.sqrt(w * w + h * h) + 1;
+        // 若使用默认时长,则需要根据水波扩散的距离来计算实际时间
+        if (durationMills == PERFECT_MILLS) {
+            // 算出实际边距与最大边距的比率
+            double rate = 1d * finalRadius / maxRadius;
+            // 水波扩散的距离与扩散时间成正比
+            durationMills = (long) (PERFECT_MILLS * rate);
+        }
+        final long finalDuration = durationMills;
+        anim.setDuration(finalDuration);
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+
+                if (requestCode == null)
+                    thisActivity.startActivity(intent);
+                else if (bundle == null)
+                    thisActivity.startActivityForResult(intent, requestCode);
+                else
+                    thisActivity.startActivityForResult(intent, requestCode, bundle);
+
+                // 默认渐隐过渡动画.
+                thisActivity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
+
+                // 默认显示返回至当前Activity的动画.
+                triggerView.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        Animator anim =
+                                ViewAnimationUtils.createCircularReveal(view, cx, cy, finalRadius, 0);
+                        anim.setDuration(finalDuration);
+                        anim.addListener(new AnimatorListenerAdapter() {
+                            @Override
+                            public void onAnimationEnd(Animator animation) {
+                                super.onAnimationEnd(animation);
+                                try {
+                                    decorView.removeView(view);
+                                } catch (Exception e) {
+                                    e.printStackTrace();
+                                }
+                            }
+                        });
+                        anim.start();
+                    }
+                }, 1000);
+
+            }
+        });
+        anim.start();
+    }
+
+
+}

+ 179 - 0
app/src/main/java/org/yczbj/ycvideoplayer/util/animation/AnimationsUtils.java

@@ -0,0 +1,179 @@
+package org.yczbj.ycvideoplayer.util.animation;
+
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.AnticipateInterpolator;
+import android.view.animation.OvershootInterpolator;
+import android.view.animation.RotateAnimation;
+import android.view.animation.ScaleAnimation;
+import android.view.animation.TranslateAnimation;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+/**
+ * ================================================
+ * 作    者:杨充
+ * 版    本:1.0
+ * 创建日期:2017/4/31
+ * 描    述:补间动画工具类
+ * 修订历史:
+ * ================================================
+ */
+public class AnimationsUtils {
+
+    /**
+     * 旋转 Rotate
+     */
+    public static Animation getRotateAnimation(float fromDegrees, float toDegrees, long durationMillis) {
+        RotateAnimation rotate = new RotateAnimation(fromDegrees, toDegrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+        rotate.setDuration(durationMillis);
+        rotate.setFillAfter(true);
+        return rotate;
+    }
+
+    /**
+     * 透明度 Alpha
+     */
+    public static Animation getAlphaAnimation(float fromAlpha, float toAlpha, long durationMillis) {
+        AlphaAnimation alpha = new AlphaAnimation(fromAlpha, toAlpha);
+        //设置持续时间
+        alpha.setDuration(durationMillis);
+        //动画结束后保留结束状态
+        alpha.setFillAfter(true);
+        //添加差值器
+        //alpha.setInterpolator(new AccelerateInterpolator());
+        return alpha;
+    }
+
+    /**
+     * 缩放 Scale
+     */
+    public static Animation getScaleAnimation(float scaleXY, long durationMillis) {
+        ScaleAnimation scale = new ScaleAnimation(1.0f, scaleXY, 1.0f, scaleXY, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+        scale.setDuration(durationMillis);
+        //scale.setFillAfter(true);
+        return scale;
+    }
+
+    /**
+     * 位移 Translate
+     */
+    public static Animation getTranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta, long durationMillis) {
+        TranslateAnimation translate = new TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta);
+        translate.setDuration(durationMillis);
+        translate.setFillAfter(true);
+        return translate;
+    }
+
+    public static Animation clickAnimation(float scaleXY, long durationMillis) {
+        AnimationSet set = new AnimationSet(true);
+        set.addAnimation(getScaleAnimation(scaleXY, durationMillis));
+        set.setDuration(durationMillis);
+        return set;
+    }
+
+    public static Animation shakeAnimation(int X) {
+        AnimationSet set = new AnimationSet(true);
+        Animation anim1 = getTranslateAnimation(0, -200, 0, 0, 100);
+        anim1.setStartOffset(100);
+        set.addAnimation(anim1);
+        Animation anim2 = getTranslateAnimation(-200, 400, 0, 0, 200);
+        anim2.setStartOffset(300);
+        set.addAnimation(anim2);
+        Animation anim3 = getTranslateAnimation(400, -200, 0, 0, 200);
+        anim3.setStartOffset(500);
+        set.addAnimation(anim3);
+        Animation anim4 = getTranslateAnimation(-200, 0, 0, 0, 100);
+        anim4.setStartOffset(600);
+        set.addAnimation(anim4);
+        set.setFillAfter(true);
+        set.setDuration(640);
+        return set;
+    }
+
+    /**
+     * 打开的动画
+     * 
+     * @param relativeLayout
+     *            子菜单容器
+     * @param menu
+     *            菜单按钮
+     * @param durationMillis
+     *            动画时间
+     */
+    public static void openAnimation(RelativeLayout relativeLayout, ImageView menu, long durationMillis) {
+        relativeLayout.setVisibility(View.VISIBLE);
+        for (int i = 1; i < relativeLayout.getChildCount(); i++) {
+            ImageView imageView = null;
+            if (relativeLayout.getChildAt(i) instanceof ImageView) {
+                imageView = (ImageView) relativeLayout.getChildAt(i);
+            } else {
+                continue;
+            }
+            int top = imageView.getTop();
+            int left = imageView.getLeft();
+            if (top == 0) {
+                top = (menu.getHeight() + 50) * i;
+            }
+            if (left == 0) {
+                left = menu.getLeft();
+            }
+            AnimationSet set = new AnimationSet(true);
+            set.addAnimation(getRotateAnimation(-360, 0, durationMillis));
+            set.addAnimation(getAlphaAnimation(0.5f, 1.0f, durationMillis));
+            // 加30是由于图片上部有一些透明高度
+            set.addAnimation(getTranslateAnimation(menu.getLeft() - left, 0, menu.getTop() - top + 30, 0, durationMillis));
+            set.setFillAfter(true);
+            set.setDuration(durationMillis);
+            set.setStartOffset((i * 100) / (-1 + relativeLayout.getChildCount()));
+            set.setInterpolator(new OvershootInterpolator(1f));
+            imageView.startAnimation(set);
+        }
+    }
+
+    /**
+     * 关闭的动画
+     * 
+     * @param relativeLayout
+     *            子菜单容器
+     * @param menu
+     *            菜单按钮
+     * @param durationMillis
+     *            动画时间
+     */
+    public static void closeAnimation(final RelativeLayout relativeLayout, final ImageView menu, long durationMillis) {
+        for (int i = 1; i < relativeLayout.getChildCount(); i++) {
+            ImageView imageView = null;
+            if (relativeLayout.getChildAt(i) instanceof ImageView) {
+                imageView = (ImageView) relativeLayout.getChildAt(i);
+            } else {
+                continue;
+            }
+            AnimationSet set = new AnimationSet(true);
+            set.addAnimation(getRotateAnimation(0, -360, durationMillis));
+            set.addAnimation(getAlphaAnimation(1.0f, 0.5f, durationMillis));
+            // 加30是由于图片上部有一些透明高度
+            set.addAnimation(getTranslateAnimation(0, menu.getLeft() - imageView.getLeft(), 0, menu.getTop() - imageView.getTop() + 30, durationMillis));
+            set.setFillAfter(true);
+            set.setDuration(durationMillis);
+            set.setStartOffset(((relativeLayout.getChildCount() - i) * 100) / (-1 + relativeLayout.getChildCount()));
+            set.setInterpolator(new AnticipateInterpolator(1f));
+            set.setAnimationListener(new Animation.AnimationListener() {
+                @Override
+                public void onAnimationStart(Animation arg0) {}
+
+                @Override
+                public void onAnimationRepeat(Animation arg0) {}
+
+                @Override
+                public void onAnimationEnd(Animation arg0) {
+                    relativeLayout.setVisibility(View.GONE);
+                }
+            });
+            imageView.startAnimation(set);
+        }
+    }
+
+}

+ 105 - 0
app/src/main/java/org/yczbj/ycvideoplayer/util/animation/AnimatorUtils.java

@@ -0,0 +1,105 @@
+package org.yczbj.ycvideoplayer.util.animation;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.view.View;
+import android.view.animation.LinearInterpolator;
+
+/**
+ * ================================================
+ * 作    者:杨充
+ * 版    本:1.0
+ * 创建日期:2017/9/31
+ * 描    述:属性动画工具类
+ * 修订历史:
+ * ================================================
+ */
+public class AnimatorUtils {
+
+
+    /**
+     * 设置属性动画ValueAnimator
+     * @param view                      view
+     * @param start                     开始值
+     * @param end                       结束值
+     * @param time                      运行时间
+     * @param delay                     延迟播放时间
+     * @param count                     重复播放次数
+     * @return                          ValueAnimator的对象
+     */
+    public static ValueAnimator setValueAnimator(View view , int start , int end , int time , int delay , int count){
+        // 步骤1:设置动画属性的初始值 & 结束值
+        //ValueAnimator.oFloat()采用默认的浮点型估值器 (FloatEvaluator)
+        //ValueAnimator.ofInt()采用默认的整型估值器(IntEvaluator)
+        ValueAnimator mAnimator = ValueAnimator.ofInt(start, end);
+        // ofInt()作用有两个
+        // 1. 创建动画实例
+        // 2. 将传入的多个Int参数进行平滑过渡:此处传入0和1,表示将值从0平滑过渡到1
+        // 如果传入了3个Int参数 a,b,c ,则是先从a平滑过渡到b,再从b平滑过渡到C,以此类推
+        // ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置,即默认设置了如何从初始值 过渡到 结束值
+        // 关于自定义插值器我将在下节进行讲解
+        // 下面看看ofInt()的源码分析 ->>关注1
+        mAnimator.setTarget(view);
+
+        // 步骤2:设置动画的播放各种属性
+        mAnimator.setDuration(time);
+        // 设置动画运行的时长
+
+        mAnimator.setStartDelay(delay);
+        // 设置动画延迟播放时间
+
+        mAnimator.setRepeatCount(count);
+        // 设置动画重复播放次数 = 重放次数+1
+        // 动画播放次数 = infinite时,动画无限重复
+
+        mAnimator.setRepeatMode(ValueAnimator.RESTART);
+        // 设置重复播放动画模式
+        // ValueAnimator.RESTART(默认):正序重放
+        // ValueAnimator.REVERSE:倒序回放
+
+        // 步骤3:将改变的值手动赋值给对象的属性值:通过动画的更新监听器
+        // 设置 值的更新监听器
+        // 即:值每次改变、变化一次,该方法就会被调用一次
+        return mAnimator;
+    }
+
+    /**
+     * 设置属性动画ObjectAnimator
+     * @param view                      操作对象
+     * @param type                      对象属性
+     * @param start                     开始值
+     * @param end                       结束值
+     * @param time                      运行时长
+     * @return                          返回ObjectAnimator对象
+     */
+    public static ObjectAnimator setObjectAnimator(View view , String type , int start , int end , long time , int delay){
+        ObjectAnimator mAnimator = ObjectAnimator.ofFloat(view, type, start, end);
+        // ofFloat()作用有两个
+        // 1. 创建动画实例
+        // 2. 参数设置:参数说明如下
+        // Object object:需要操作的对象
+        // String property:需要操作的对象的属性
+        // property属性值常见有:此处先展示四种基本变换:平移、旋转、缩放 & 透明度   translationX  rotation scaleX alpha
+        // float ....values:动画初始值 & 结束值(不固定长度)
+        // 若是两个参数a,b,则动画效果则是从属性的a值到b值
+        // 若是三个参数a,b,c,则则动画效果则是从属性的a值到b值再到c值
+        // 以此类推
+        // 至于如何从初始值 过渡到 结束值,同样是由估值器决定,此处ObjectAnimator.ofFloat()是有系统内置的浮点型估值器FloatEvaluator,同ValueAnimator讲解
+
+        // 设置动画重复播放次数 = 重放次数+1
+        // 动画播放次数 = infinite时,动画无限重复
+        mAnimator.setRepeatCount(ValueAnimator.INFINITE);
+        // 设置动画运行的时长
+        mAnimator.setDuration(time);
+        // 设置动画延迟播放时间
+        mAnimator.setStartDelay(delay);
+        // 设置重复播放动画模式
+        mAnimator.setRepeatMode(ValueAnimator.RESTART);
+        // ValueAnimator.RESTART(默认):正序重放
+        // ValueAnimator.REVERSE:倒序回放
+        //设置差值器
+        mAnimator.setInterpolator(new LinearInterpolator());
+        return mAnimator;
+    }
+
+}

BIN
app/src/main/res/drawable-xhdpi/icon_binding_hint.png


BIN
app/src/main/res/drawable-xxhdpi/icon_search_normal.png


+ 8 - 0
app/src/main/res/drawable/shape_search_bg.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="#E7E7E7"/>
+    <corners android:radius="100dp" />
+
+</shape>

+ 19 - 0
app/src/main/res/layout/activity_test_dl_my.xml

@@ -26,4 +26,23 @@
         android:gravity="left|center_vertical"
         android:text="2.跳转到我的下载页面,看缓冲是否同步"/>
 
+
+    <TextView
+        android:id="@+id/tv_1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="10dp"
+        android:layout_margin="10dp"
+        android:background="@color/gray3"
+        android:text="我的视频缓存"/>
+
+    <TextView
+        android:id="@+id/tv_2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="10dp"
+        android:layout_margin="10dp"
+        android:background="@color/gray3"
+        android:text="我的音频缓存"/>
+
 </LinearLayout>

+ 70 - 0
app/src/main/res/layout/fragment_home.xml

@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.support.v7.widget.Toolbar
+        android:layout_width="match_parent"
+        android:layout_height="45dp"
+        app:contentInsetStart="0dp"
+        android:visibility="gone">
+        <LinearLayout
+            android:id="@+id/ll_search"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:gravity="center"
+            android:paddingBottom="8dp"
+            android:paddingTop="8dp"
+            android:layout_marginStart="10dp"
+            android:layout_marginEnd="10dp"
+            android:background="@drawable/shape_search_bg">
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:src="@drawable/icon_search_normal"/>
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_marginStart="10dp"
+                android:textColor="@color/blackText2"
+                android:textSize="12sp"
+                android:text="搜索更多音视频资源"/>
+        </LinearLayout>
+
+    </android.support.v7.widget.Toolbar>
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <include layout="@layout/base_refresh_recycler_view"/>
+
+        <LinearLayout
+            android:id="@+id/ll_bind"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:background="@color/alpha_50_black">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:padding="10dp"
+                android:gravity="center"
+                android:layout_gravity="center"
+                android:drawableStart="@drawable/icon_binding_hint"
+                android:drawablePadding="8dp"
+                android:textColor="@color/redTab"
+                android:textSize="13sp"
+                android:text="绑定手机号立即获取3天会员资格"/>
+        </LinearLayout>
+    </FrameLayout>
+
+
+
+
+</LinearLayout>

+ 107 - 0
app/src/main/res/layout/item_news_article_img.xml

@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.CardView
+    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:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginBottom="4dp"
+    android:layout_marginTop="4dp"
+    app:cardElevation="1dp">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="?attr/selectableItemBackground"
+        android:foreground="?attr/selectableItemBackground"
+        android:padding="16dp">
+
+        <LinearLayout
+            android:id="@+id/header"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:id="@+id/iv_media"
+                android:layout_width="22dp"
+                android:layout_height="22dp"
+                android:scaleType="centerCrop"/>
+
+            <TextView
+                android:id="@+id/tv_extra"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="8dp"
+                android:layout_marginStart="8dp"
+                android:ellipsize="end"
+                android:maxLength="30"
+                android:maxLines="1"
+                android:textAppearance="@style/TextAppearance.AppCompat.Caption"
+                tools:text="新闻源 - 2222条评论 - 1小时前"/>
+
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <ImageView
+                    android:id="@+id/iv_dots"
+                    android:layout_width="22dp"
+                    android:layout_height="22dp"
+                    android:layout_alignParentEnd="true"
+                    android:layout_alignParentRight="true"
+                    android:layout_centerVertical="true"
+                    android:padding="4dp"
+                    android:scaleType="center"
+                    app:srcCompat="@drawable/ic_dots_grey_24dp"
+                    tools:ignore="ContentDescription,VectorDrawableCompat"/>
+            </RelativeLayout>
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/ll_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/header"
+            android:layout_marginTop="4dp">
+
+            <LinearLayout
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_marginEnd="8dp"
+                android:layout_marginRight="8dp"
+                android:layout_weight="1"
+                android:orientation="vertical">
+
+                <TextView
+                    android:id="@+id/tv_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:ellipsize="end"
+                    android:maxLines="2"
+                    android:textStyle="bold"
+                    tools:text="菲总统称中国将向菲提供武器 已指示军方前往接收"/>
+
+                <TextView
+                    android:id="@+id/tv_abstract"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="4dp"
+                    android:ellipsize="end"
+                    android:maxLines="3"
+                    tools:text="美国总统当选人特朗普日前暗示,可能拿美国的“一中政策”当谈判筹码,与中国大陆就诸如人民币汇率及南海等争议讨价还价。"/>
+            </LinearLayout>
+
+            <ImageView
+                android:id="@+id/iv_image"
+                android:layout_width="72dp"
+                android:layout_height="72dp"
+                android:layout_marginLeft="8dp"
+                android:layout_marginStart="8dp"
+                tools:ignore="ContentDescription"/>
+
+        </LinearLayout>
+    </RelativeLayout>
+</android.support.v7.widget.CardView>

+ 92 - 0
app/src/main/res/layout/item_news_article_text.xml

@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.v7.widget.CardView
+    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:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginBottom="4dp"
+    android:layout_marginTop="4dp"
+    app:cardElevation="1dp">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="?attr/selectableItemBackground"
+        android:foreground="?attr/selectableItemBackground"
+        android:padding="16dp">
+
+        <LinearLayout
+            android:id="@+id/header"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:id="@+id/iv_media"
+                android:layout_width="22dp"
+                android:layout_height="22dp"
+                android:scaleType="centerCrop"/>
+
+            <TextView
+                android:id="@+id/tv_extra"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="8dp"
+                android:layout_marginStart="8dp"
+                android:ellipsize="end"
+                android:maxLength="30"
+                android:maxLines="1"
+                android:textAppearance="@style/TextAppearance.AppCompat.Caption"
+                tools:text="新闻源 - 2222条评论 - 1小时前"/>
+
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <ImageView
+                    android:id="@+id/iv_dots"
+                    android:layout_width="22dp"
+                    android:layout_height="22dp"
+                    android:layout_alignParentEnd="true"
+                    android:layout_alignParentRight="true"
+                    android:layout_centerVertical="true"
+                    android:padding="4dp"
+                    android:scaleType="center"
+                    app:srcCompat="@drawable/ic_dots_grey_24dp"
+                    tools:ignore="ContentDescription,VectorDrawableCompat"/>
+            </RelativeLayout>
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@+id/header"
+            android:layout_marginTop="4dp"
+            android:orientation="vertical">
+
+            <TextView
+                android:id="@+id/tv_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ellipsize="end"
+                android:maxLines="2"
+                android:textStyle="bold"
+                tools:text="菲总统称中国将向菲提供武器 已指示军方前往接收"/>
+
+            <TextView
+                android:id="@+id/tv_abstract"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:ellipsize="end"
+                android:maxLines="3"
+                tools:text="美国总统当选人特朗普日前暗示,可能拿美国的“一中政策”当谈判筹码,与中国大陆就诸如人民币汇率及南海等争议讨价还价。"/>
+
+        </LinearLayout>
+    </RelativeLayout>
+
+</android.support.v7.widget.CardView>

+ 7 - 4
app/src/main/res/values/array.xml

@@ -5,22 +5,25 @@
     <!--首页底部导航栏的标题,未选中时-->
     <integer-array name="main_tab_un_select">
         <item name="tab_home">@drawable/tab_home_unselect</item>
-        <item name="tab_find">@drawable/tab_speech_unselect</item>
-        <item name="tab_data">@drawable/tab_contact_unselect</item>
+        <item name="tab_news">@drawable/tab_speech_unselect</item>
+        <item name="tab_find">@drawable/tab_contact_unselect</item>
+        <item name="tab_data">@drawable/tab_speech_unselect</item>
         <item name="tab_me">@drawable/tab_more_unselect</item>
     </integer-array>
 
     <!--首页底部导航栏的标题,选中时-->
     <integer-array name="main_tab_select">
         <item name="tab_home">@drawable/tab_home_select</item>
-        <item name="tab_find">@drawable/tab_speech_select</item>
-        <item name="tab_data">@drawable/tab_contact_select</item>
+        <item name="tab_news">@drawable/tab_speech_select</item>
+        <item name="tab_find">@drawable/tab_contact_select</item>
+        <item name="tab_data">@drawable/tab_speech_select</item>
         <item name="tab_me">@drawable/tab_more_select</item>
     </integer-array>
 
     <!--首页底部导航栏文字-->
     <string-array name="main_title">
         <item>首页</item>
+        <item>新闻</item>
         <item>专题</item>
         <item>视频</item>
         <item>我的</item>

+ 120 - 0
app/src/main/res/values/array_news.xml

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!--需要单独处理的 视频 / 段子 / 问答 -->
+    <string-array name="mobile_news_name">
+        <item>推荐</item>
+        <item>热点</item>
+        <item>视频</item>
+        <item>社会</item>
+        <item>娱乐</item>
+        <item>科技</item>
+
+        <item>问答</item>
+        <item>汽车</item>
+        <item>财经</item>
+        <item>军事</item>
+        <item>体育</item>
+
+        <item>段子</item>
+        <item>国际</item>
+        <item>健康</item>
+        <item>房产</item>
+        <item>育儿</item>
+        <item>数码</item>
+
+        <item>美食</item>
+        <item>养生</item>
+        <item>电影</item>
+        <item>手机</item>
+        <item>教育</item>
+
+        <item>旅游</item>
+        <item>宠物</item>
+        <item>文化</item>
+        <item>故事</item>
+        <item>游戏</item>
+
+        <item>股票</item>
+        <item>动漫</item>
+        <item>情感</item>
+        <item>精选</item>
+        <item>星座</item>
+
+        <item>家居</item>
+        <item>三农</item>
+        <item>孕产</item>
+        <item>收藏</item>
+        <item>时尚</item>
+
+        <item>历史</item>
+        <item>搞笑</item>
+        <item>辟谣</item>
+        <item>中国新唱将</item>
+        <item>彩票</item>
+
+        <item>快乐男声</item>
+        <item>正能量</item>
+        <item>政务</item>
+        <item>探索</item>
+
+    </string-array>
+
+    <string-array name="mobile_news_id">
+        <item> </item>
+        <item>news_hot</item>
+        <item>video</item>
+        <item>news_society</item>
+        <item>news_entertainment</item>
+        <item>news_tech</item>
+
+        <item>question_and_answer</item>
+        <item>news_car</item>
+        <item>news_finance</item>
+        <item>news_military</item>
+        <item>news_sports</item>
+
+        <item>essay_joke</item>
+        <item>news_world</item>
+        <item>news_health</item>
+        <item>news_house</item>
+        <item>news_baby</item>
+        <item>digital</item>
+
+        <item>news_food</item>
+        <item>news_regimen</item>
+        <item>movie</item>
+        <item>cellphone</item>
+        <item>news_edu</item>
+
+        <item>news_travel</item>
+        <item>宠物</item>
+        <item>news_culture</item>
+        <item>news_story</item>
+        <item>news_game</item>
+
+        <item>stock</item>
+        <item>news_comic</item>
+        <item>emotion</item>
+        <item>boutique</item>
+        <item>news_astrology</item>
+
+        <item>news_home</item>
+        <item>news_agriculture</item>
+        <item>pregnancy</item>
+        <item>news_collect</item>
+        <item>news_fashion</item>
+
+        <item>news_history</item>
+        <item>funny</item>
+        <item>rumor</item>
+        <item>中国新唱将</item>
+        <item>彩票</item>
+
+        <item>快乐男声</item>
+        <item>positive</item>
+        <item>government</item>
+        <item>news_discovery</item>
+    </string-array>
+
+</resources>

+ 23 - 0
app/src/main/res/values/colors.xml

@@ -45,4 +45,27 @@
     <!-- 底部导航选择红色 -->
     <color name="redTab">#D03E49</color>
 
+
+    <!--透明度颜色-->
+    <color name="alpha_15_white">#26FFFFFF</color>
+    <color name="alpha_05_black">#0D000000</color>
+    <color name="alpha_10_black">#1A000000</color>
+    <color name="alpha_15_black">#26000000</color>
+    <color name="alpha_20_black">#33000000</color>
+    <color name="alpha_25_black">#40000000</color>
+    <color name="alpha_30_black">#4D000000</color>
+    <color name="alpha_35_black">#59000000</color>
+    <color name="alpha_40_black">#66000000</color>
+    <color name="alpha_45_black">#73000000</color>
+    <color name="alpha_50_black">#80000000</color>
+    <color name="alpha_55_black">#8C000000</color>
+    <color name="alpha_60_black">#99000000</color>
+    <color name="alpha_65_black">#A6000000</color>
+    <color name="alpha_70_black">#B3000000</color>
+    <color name="alpha_75_black">#BF000000</color>
+    <color name="alpha_80_black">#CC000000</color>
+    <color name="alpha_85_black">#D9000000</color>
+    <color name="alpha_90_black">#E6000000</color>
+    <color name="alpha_95_black">#F2000000</color>
+
 </resources>

+ 6 - 0
app/src/main/res/values/styles.xml

@@ -62,4 +62,10 @@
         <item name="android:windowExitAnimation">@anim/photo_dialog_out_anim</item>
     </style>
 
+    <!--设置动画效果-->
+    <style name="main_menu_animStyle">
+        <item name="android:windowEnterAnimation">@anim/photo_dialog_in_anim</item>
+        <item name="android:windowExitAnimation">@anim/photo_dialog_out_anim</item>
+    </style>
+
 </resources>