zoukankan      html  css  js  c++  java
  • TouTiao开源项目 分析笔记20 问答详情


    1.效果预览

    1.1.效果预览,从问答列表开始

      

      前面实现了从列表到内容。

      这里主要讲解从内容到详情。

      点击每一个回答内容,进入回答详情页面。

    1.2.触发的点击事件

      在WendaContentViewBinder中,设置item点击事件:

      WendaDetailActivity.lauch(bean);


    2.问答详情的活动页面

    2.1.源代码

    public class WendaDetailActivity extends BaseActivity {
    
        private static final String TAG = "WendaDetailActivity";
    
        public static void launch(WendaContentBean.AnsListBean bean) {
            InitApp.AppContext.startActivity(new Intent(InitApp.AppContext, WendaDetailActivity.class)
                    .putExtra(TAG, bean)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_wenda_content_view);
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.container, WendaDetailFragment.newInstance(getIntent().getParcelableExtra(TAG)))
                    .commit();
        }
    }

    2.2.需要的布局

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/viewBackground"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:layout="@layout/fragment_news_tab"
        >
    
    </FrameLayout>

    2.3.清单中活动配置

    <activity
                android:name=".module.wenda.detail.WendaDetailActivity"
                android:configChanges="orientation|screenSize|uiMode"
                android:label="@string/title_wenda_detail"
                android:theme="@style/AppTheme.NoActionBar.Slidable"/>


    3.问答详情页面片段

    3.1.需要实现的底层接口

    public interface IWendaDetail {
        interface View extends IBaseListView<Presenter> {
    
            /**
             * 加载网页
             */
            void onSetWebView(String baseUrl, boolean flag);
    
            /**
             * 请求数据
             */
            void onLoadData();
        }
    
        interface Presenter extends IBasePresenter {
    
            /**
             * 请求数据
             */
            void doLoadData(String url);
    
            /**
             * 加载评论
             */
            void doLoadComment(String... ansId);
    
            /**
             * 加载更多评论
             */
            void doLoadMoreComment();
    
            /**
             * 设置适配器
             */
            void doSetAdapter(List<NewsCommentBean.DataBean.CommentBean> list);
    
            /**
             * 加载完毕
             */
            void doShowNoMore();
        }
    }

    3.2.片段源代码 

    public class WendaDetailFragment extends BaseFragment<IWendaDetail.Presenter> implements IWendaDetail.View{
    
        private static final String TAG = "WendaDetailFragment";
        private WendaContentBean.AnsListBean bean = null;
        private String url;
        private String title;
        private String shareTitle;
    
        private WebView webView;
        private NestedScrollView scrollView;
        private ContentLoadingProgressBar progressBar;
        private TextView tv_title;
        private CircleImageView iv_user_avatar;
        private TextView tv_user_name;
        private RecyclerView recyclerView;
        private LinearLayout header_layout;
        private SwipeRefreshLayout swipeRefreshLayout;
    
        private MultiTypeAdapter adapter;
        private boolean canLoadMore;
        private Items oldItems = new Items();
    
        public static WendaDetailFragment newInstance(Parcelable bean) {
            Bundle args = new Bundle();
            args.putParcelable(TAG, bean);
            WendaDetailFragment fragment = new WendaDetailFragment();
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        protected void initData() {
            bean = getArguments().getParcelable(TAG);
            if (null == this.bean) {
                onShowNetError();
                return;
            }
            url = bean.getShare_data().getShare_url();
            onLoadData();
    
            ImageLoader.loadCenterCrop(getActivity(), bean.getUser().getAvatar_url(), iv_user_avatar, R.color.viewBackground);
            tv_title.setText(bean.getTitle());
            tv_user_name.setText(bean.getUser().getUname());
            shareTitle = bean.getShare_data().getTitle();
            header_layout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    WendaContentActivity.launch(bean.getQid());
                }
            });
        }
    
        @Override
        public void onLoadData() {
            presenter.doLoadData(url);
        }
    
        @Override
        public void setPresenter(IWendaDetail.Presenter presenter) {
            if (null == presenter) {
                this.presenter = new WendaDetailPresenter(this);
            }
        }
    
        @Override
        public void onSetAdapter(List<?> list) {
            Items newItems = new Items(list);
            newItems.add(new LoadingBean());
            DiffCallback.notifyDataSetChanged(oldItems, newItems, DiffCallback.NEWS_COMMENT, adapter);
            oldItems.clear();
            oldItems.addAll(newItems);
            canLoadMore = true;
            recyclerView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        }
    
        @Override
        protected int attachLayoutId() {
            return R.layout.fragment_wenda_detail;
        }
    
        @Override
        protected void initView(View view) {
            Toolbar toolbar = view.findViewById(R.id.toolbar);
            initToolBar(toolbar, true, getString(R.string.title_wenda_detail));
            toolbar.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    scrollView.smoothScrollTo(0, 0);
                }
            });
    
            webView = view.findViewById(R.id.webview);
            initWebClient();
    
            header_layout = view.findViewById(R.id.header_layout);
            header_layout.setBackgroundColor(SettingUtil.getInstance().getColor());
    
            tv_title = view.findViewById(R.id.tv_title);
            iv_user_avatar = view.findViewById(R.id.iv_user_avatar);
            tv_user_name = view.findViewById(R.id.tv_user_name);
    
            scrollView = view.findViewById(R.id.scrollView);
            scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
                @Override
                public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    onHideLoading();
                }
            });
            scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
                @Override
                public void onScrollChanged() {
                    View view = scrollView.getChildAt(scrollView.getChildCount() - 1);
                    int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));
                    if (diff == 0) {
                        canLoadMore = false;
                        presenter.doLoadMoreComment();
                    }
                }
            });
    
            swipeRefreshLayout = view.findViewById(R.id.refresh_layout);
            swipeRefreshLayout.setColorSchemeColors(SettingUtil.getInstance().getColor());
            swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    swipeRefreshLayout.post(new Runnable() {
                        @Override
                        public void run() {
                            swipeRefreshLayout.setRefreshing(true);
                        }
                    });
                    presenter.doLoadData(url);
                }
            });
    
            progressBar = view.findViewById(R.id.pb_progress);
            int color = SettingUtil.getInstance().getColor();
            progressBar.getIndeterminateDrawable().setColorFilter(color, PorterDuff.Mode.MULTIPLY);
            progressBar.show();
    
            recyclerView = view.findViewById(R.id.recycler_view);
            recyclerView.setHasFixedSize(true);
            // 禁止嵌套滚动
            recyclerView.setNestedScrollingEnabled(false);
            adapter = new MultiTypeAdapter(oldItems);
            Register.registerNewsCommentItem(adapter);
            recyclerView.setAdapter(adapter);
    
            setHasOptionsMenu(true);
        }
    
        @Override
        public void onSetWebView(String url, boolean flag) {
            // 是否解析网页成功
            if (flag) {
                webView.loadDataWithBaseURL(null, url, "text/html", "utf-8", null);
                presenter.doLoadComment(bean.getAnsid());
            } else {
                webView.loadUrl(url);
            }
        }
    
        @SuppressLint("SetJavaScriptEnabled")
        private void initWebClient() {
            WebSettings settings = webView.getSettings();
            settings.setJavaScriptEnabled(true);
            // 缩放,设置为不能缩放可以防止页面上出现放大和缩小的图标
            settings.setBuiltInZoomControls(false);
            // 缓存
            settings.setCacheMode(WebSettings.LOAD_DEFAULT);
            // 开启DOM storage API功能
            settings.setDomStorageEnabled(true);
            // 开启application Cache功能
            settings.setAppCacheEnabled(true);
            // 判断是否为无图模式
            settings.setBlockNetworkImage(SettingUtil.getInstance().getIsNoPhotoMode());
            // 不调用第三方浏览器即可进行页面反应
            webView.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    if (!TextUtils.isEmpty(url)) {
                        view.loadUrl(url);
                    }
                    return true;
                }
    
                @Override
                public void onPageFinished(WebView view, String url) {
                    onHideLoading();
                    super.onPageFinished(view, url);
                }
            });
    
            webView.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View view, int i, KeyEvent keyEvent) {
                    if ((keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
                        webView.goBack();
                        return true;
                    }
                    return false;
                }
            });
    
            webView.setWebChromeClient(new WebChromeClient() {
                @Override
                public void onProgressChanged(WebView view, int newProgress) {
                    super.onProgressChanged(view, newProgress);
                    if (newProgress >= 90) {
                        onHideLoading();
                    } else {
                        onShowLoading();
                    }
                }
            });
        }
    
        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            super.onCreateOptionsMenu(menu, inflater);
            inflater.inflate(R.menu.menu_wenda_detail, menu);
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            if (item.getItemId() == R.id.action_wenda_share) {
                IntentAction.send(getActivity(), shareTitle + "
    " + url);
            }
            return super.onOptionsItemSelected(item);
        }
    
        @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 onShowLoading() {
            progressBar.show();
        }
    
        @Override
        public void onHideLoading() {
            progressBar.hide();
            swipeRefreshLayout.post(new Runnable() {
                @Override
                public void run() {
                    swipeRefreshLayout.setRefreshing(false);
                }
            });
        }
    
        @Override
        public void onShowNetError() {
            Snackbar.make(scrollView, R.string.network_error, Snackbar.LENGTH_SHORT).show();
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    adapter.setItems(new Items());
                    adapter.notifyDataSetChanged();
                    canLoadMore = false;
                }
            });
        }
    }
    View Code

    3.3.新建实例。

      传进去一个bean类。

      传出去一个片段。

    3.4.初始化视图。

      获取toolbar,并进行相关设置。

      获取webview,设置一些交互属性。

      获取头部布局,设置颜色。

      获取scrollView,设置滑动监听,以及设置观察树。

      获取刷新圈,设置刷新事件。

      获取进度条,设置颜色。

      获取recyclerView,设置适配器。

      设置菜单。

    3.5.重写设置WebView。

      判断是否解析网页成功。

    3.6.初始化webClient,设置webView的配置。

    3.7.设置菜单。

    3.8.重写没有更多了,重写显示加载,重写隐藏加载,重写网络错误。

    3.9.重写设置适配器和设置处理器。

    3.10.重写布局。

      需要的布局==>fragment_wenda_detail.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/news_content_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
    
        <include layout="@layout/toolbar"/>
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fadeScrollbars="true"
            android:scrollbarFadeDuration="1"
            android:scrollbars="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
            <android.support.v4.widget.SwipeRefreshLayout
                android:id="@+id/refresh_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    
                <android.support.v4.widget.NestedScrollView
                    android:id="@+id/scrollView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
    
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:orientation="vertical">
    
                        <LinearLayout
                            android:id="@+id/header_layout"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:background="?attr/selectableItemBackground"
                            android:foreground="?attr/selectableItemBackground"
                            android:orientation="vertical">
    
                            <TextView
                                android:id="@+id/tv_title"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:ellipsize="end"
                                android:maxLines="2"
                                android:padding="16dp"
                                android:textAppearance="@style/TextAppearance.AppCompat.Title"
                                android:textColor="@color/White"
                                tools:text="都说床头不能朝西,有什么说法吗?"/>
    
                        </LinearLayout>
    
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:background="@color/viewBackground"
                            android:gravity="center_vertical"
                            android:padding="8dp">
    
                            <com.jasonjan.headnews.widget.CircleImageView
                                android:id="@+id/iv_user_avatar"
                                android:layout_width="36dp"
                                android:layout_height="36dp"
                                android:scaleType="centerCrop"
                                android:src="@color/Black" />
    
                            <TextView
                                android:id="@+id/tv_user_name"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginLeft="8dp"
                                android:layout_marginStart="8dp"
                                android:ellipsize="end"
                                android:maxLines="1"
                                tools:text="用户名"/>
                        </LinearLayout>
    
                        <View
                            android:id="@+id/divider"
                            android:layout_width="match_parent"
                            android:layout_height="1px"
                            android:background="@color/line_divider"/>
    
                        <WebView
                            android:id="@+id/webview"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"/>
    
                        <android.support.v7.widget.RecyclerView
                            android:id="@+id/recycler_view"
                            android:layout_width="match_parent"
                            android:layout_height="match_parent"
                            android:fadeScrollbars="true"
                            android:scrollbarFadeDuration="1"
                            android:scrollbars="vertical"
                            app:layoutManager="LinearLayoutManager"/>
                    </LinearLayout>
    
                </android.support.v4.widget.NestedScrollView>
    
            </android.support.v4.widget.SwipeRefreshLayout>
    
            <android.support.v4.widget.ContentLoadingProgressBar
                android:id="@+id/pb_progress"
                style="?android:attr/progressBarStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"/>
    
        </RelativeLayout>
    
    </android.support.design.widget.CoordinatorLayout>
    View Code

      预览图片:

      


    4.问答详情处理器

    4.1.需要第三方库Jsoup的支持

      请参考这篇文章:使用Jsoup解析HTML

      在build.gradle中这样配置:

    // 解析HTML
        implementation 'org.jsoup:jsoup:1.10.2'

      参考的官方网站:http://jsoup.org/

      

    4.2.源代码 

    public class WendaDetailPresenter implements IWendaDetail.Presenter {
        private IWendaDetail.View view;
        private String groupId;
        private int offset = 0;
        private List<NewsCommentBean.DataBean.CommentBean> commentsBeanList = new ArrayList<>();
    
        WendaDetailPresenter(IWendaDetail.View view) {
            this.view = view;
        }
    
        @Override
        public void doRefresh() {
            if (commentsBeanList.size() != 0) {
                commentsBeanList.clear();
                offset = 0;
            }
            view.onLoadData();
        }
    
        @Override
        public void doLoadData(String url) {
            RetrofitFactory.getRetrofit().create(IMobileWendaApi.class)
                    .getWendaAnsDetail(url)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<ResponseBody>() {
                        @Override
                        public void accept(@NonNull ResponseBody responseBody) throws Exception {
                            String result = getHTML(responseBody.string());
                            if (result != null) {
                                view.onSetWebView(result, true);
                            } else {
                                view.onSetWebView(null, false);
                            }
                            view.onHideLoading();
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(@NonNull Throwable throwable) throws Exception {
                            view.onSetWebView(null, false);
                            view.onHideLoading();
                            ErrorAction.print(throwable);
                        }
                    });
        }
    
        private String getHTML(String response) {
            Document doc = Jsoup.parse(response, "UTF-8");
            Elements elements = doc.getElementsByClass("con-words");
            String content = null;
            for (Element element : elements) {
                content = element.toString();
                break;
            }
            if (content != null) {
    
                String css = "<link rel="stylesheet" href="file:///android_asset/toutiao_light.css" type="text/css">";
                if (SettingUtil.getInstance().getIsNightMode()) {
                    css = css.replace("toutiao_light", "toutiao_dark");
                }
    
                String html = "<!DOCTYPE html>
    " +
                        "<html lang="en">
    " +
                        "<head>
    " +
                        "    <meta charset="UTF-8">" +
                        css +
                        "<body>
    " +
                        "<article class="article-container">
    " +
                        "    <div class="article__content article-content">" +
                        content +
                        "    </div>
    " +
                        "</article>
    " +
                        "</body>
    " +
                        "</html>";
    
                return html;
            } else {
                return null;
            }
        }
    
        @Override
        public void doLoadComment (String...ansId){
    
            try {
                if (null == groupId) {
                    this.groupId = ansId[0];
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                e.printStackTrace();
            }
    
            RetrofitFactory.getRetrofit().create(IMobileNewsApi.class)
                    .getNewsComment(groupId, offset)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(new Function<NewsCommentBean, List<NewsCommentBean.DataBean.CommentBean>>() {
                        @Override
                        public List<NewsCommentBean.DataBean.CommentBean> apply(@NonNull NewsCommentBean newsCommentBean) throws Exception {
                            List<NewsCommentBean.DataBean.CommentBean> data = new ArrayList<>();
                            for (NewsCommentBean.DataBean bean : newsCommentBean.getData()) {
                                data.add(bean.getComment());
                            }
                            return data;
                        }
                    })
                    .compose(view.<List<NewsCommentBean.DataBean.CommentBean>>bindToLife())
                    .subscribe(new Consumer<List<NewsCommentBean.DataBean.CommentBean>>() {
                        @Override
                        public void accept(@NonNull List<NewsCommentBean.DataBean.CommentBean> list) throws Exception {
                            if (list.size() > 0) {
                                doSetAdapter(list);
                            } else {
                                doShowNoMore();
                            }
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(@NonNull Throwable throwable) throws Exception {
                            doShowNetError();
                            ErrorAction.print(throwable);
                        }
                    });
        }
    
        @Override
        public void doLoadMoreComment () {
            offset += 10;
            doLoadComment();
        }
    
        @Override
        public void doSetAdapter (List < NewsCommentBean.DataBean.CommentBean > list) {
            commentsBeanList.addAll(list);
            view.onSetAdapter(commentsBeanList);
            view.onHideLoading();
        }
    
        @Override
        public void doShowNetError () {
            view.onHideLoading();
            view.onShowNetError();
        }
    
        @Override
        public void doShowNoMore () {
            view.onHideLoading();
            if (commentsBeanList.size() > 0) {
                view.onShowNoMore();
            }
        }
        
    }

    4.3.构造函数,传入一个视图层。

    4.4.重写刷新函数,调用视图层的加载。

    4.5.重写加载数据,调用API。

    4.6.获取HTML的一个函数。

      传进去一个response的字符串。

      利用Jsoup解析这个字符串,然后得到一个html。

      方法源代码: 

    private String getHTML(String response) {
            Document doc = Jsoup.parse(response, "UTF-8");
            Elements elements = doc.getElementsByClass("con-words");
            String content = null;
            for (Element element : elements) {
                content = element.toString();
                break;
            }
            if (content != null) {
    
                String css = "<link rel="stylesheet" href="file:///android_asset/toutiao_light.css" type="text/css">";
                if (SettingUtil.getInstance().getIsNightMode()) {
                    css = css.replace("toutiao_light", "toutiao_dark");
                }
    
                String html = "<!DOCTYPE html>
    " +
                        "<html lang="en">
    " +
                        "<head>
    " +
                        "    <meta charset="UTF-8">" +
                        css +
                        "<body>
    " +
                        "<article class="article-container">
    " +
                        "    <div class="article__content article-content">" +
                        content +
                        "    </div>
    " +
                        "</article>
    " +
                        "</body>
    " +
                        "</html>";
    
                return html;
            } else {
                return null;
            }
        }

      

    4.7.重写加载评论。

      调用API,请求获取问答详情的评论。

      

    4.8.重写加载更多评论。

    4.9.重写设置适配器。

      传进去一个List。

    4.10.重写网络异常,没有更多了。


    5.问答详情评论的视图绑定

    5.1.这里用的依旧是新闻页面的视图绑定

      在WendaDetailFragment中的一个initView中引用。

     Register.registerNewsCommentItem(adapter);

      在Register中注册数据类型。

    /**
         * 新闻评论
         * @param adapter
         */
        public static void registerNewsCommentItem(@NonNull MultiTypeAdapter adapter) {
            adapter.register(NewsCommentBean.DataBean.CommentBean.class, new NewsCommentViewBinder());
            adapter.register(LoadingBean.class, new LoadingViewBinder());
            adapter.register(LoadingEndBean.class, new LoadingEndViewBinder());
        }

    5.2.回顾一下新闻评论的视图绑定

    public class NewsCommentViewBinder extends ItemViewBinder<NewsCommentBean.DataBean.CommentBean,NewsCommentViewBinder.ViewHolder> {
    
        @NonNull
        @Override
        protected NewsCommentViewBinder.ViewHolder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
            View view = inflater.inflate(R.layout.item_news_comment, parent, false);
            return new ViewHolder(view);
        }
    
        @Override
        protected void onBindViewHolder(@NonNull final ViewHolder holder, @NonNull final NewsCommentBean.DataBean.CommentBean item) {
    
            final Context context = holder.itemView.getContext();
    
            try {
                String iv_avatar = item.getUser_profile_image_url();
                String tv_username = item.getUser_name();
                String tv_text = item.getText();
                int tv_likes = item.getDigg_count();
    
                ImageLoader.loadCenterCrop(context, iv_avatar, holder.iv_avatar, R.color.viewBackground);
                holder.tv_username.setText(tv_username);
                holder.tv_text.setText(tv_text);
                holder.tv_likes.setText(tv_likes + "赞");
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        final String content = item.getText();
                        final BottomSheetDialogFixed dialog = new BottomSheetDialogFixed(context);
                        dialog.setOwnerActivity((BaseActivity) context);
                        View view = ((BaseActivity) context).getLayoutInflater().inflate(R.layout.item_comment_action_sheet, null);
                        view.findViewById(R.id.layout_copy_text).setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                ClipboardManager copy = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
                                ClipData clipData = ClipData.newPlainText("text", content);
                                copy.setPrimaryClip(clipData);
                                Snackbar.make(holder.itemView, R.string.copied_to_clipboard, Snackbar.LENGTH_SHORT).show();
                                dialog.dismiss();
                            }
                        });
                        view.findViewById(R.id.layout_share_text).setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                IntentAction.send(context, content);
                                dialog.dismiss();
                            }
                        });
                        dialog.setContentView(view);
                        dialog.show();
                    }
                });
            } catch (Exception e) {
                ErrorAction.print(e);
            }
        }
    
        public class ViewHolder extends RecyclerView.ViewHolder {
    
            private ImageView iv_avatar;
            private TextView tv_username;
            private TextView tv_text;
            private TextView tv_likes;
    
            public ViewHolder(View itemView) {
                super(itemView);
                this.iv_avatar = itemView.findViewById(R.id.iv_avatar);
                this.tv_username = itemView.findViewById(R.id.tv_username);
                this.tv_text = itemView.findViewById(R.id.tv_text);
                this.tv_likes = itemView.findViewById(R.id.tv_likes);
            }
        }
    }

      需要item布局==>item_news_comment.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/viewBackground">
    
        <LinearLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/selectableItemBackground"
            android:foreground="?attr/selectableItemBackground"
            android:orientation="vertical"
            android:paddingBottom="8dp"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:paddingTop="8dp">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <com.jasonjan.headnews.widget.CircleImageView
                    android:id="@+id/iv_avatar"
                    android:layout_width="22dp"
                    android:layout_height="22dp"
                    android:layout_gravity="center"/>
    
                <TextView
                    android:id="@+id/tv_username"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="8dp"
                    android:layout_marginStart="8dp"
                    android:ellipsize="end"
                    android:maxLines="1"
                    tools:text="小恢恢的帽子"/>
    
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/tv_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    tools:text="光看个开头就笑的不行了,咱们中国有个传统,就是家里来客人了,要到门口迎一下,如果手里还带着礼物,那要先接过来,因为人家大老远一路带过来的,已经很累了,更何况老美不远万里带过来的呢,如果不接过来那也太不像话了,会让国际笑话中国,也有失大国风范!这也是一种礼貌,更是中华民族的传统美德!"/>
    
                <TextView
                    android:id="@+id/tv_likes"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="2dp"
                    android:gravity="end"
                    android:maxLines="1"
                    tools:text="4832赞"/>
    
            </LinearLayout>
        </LinearLayout>
    
        <View
            android:id="@+id/divider"
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:layout_below="@+id/content"
            android:background="@color/line_divider"/>
    
    </RelativeLayout>

      效果预览:

      


    6.API请求

    6.1.获取头条回答正文

     /**
         * 获取头条问答回答正文
         */
        @GET
        @Headers("User-Agent:" + Constant.USER_AGENT_MOBILE)
        Observable<ResponseBody> getWendaAnsDetail(@Url String url);

      传进去一个url。

      传出来一个Observable<ResponseBody>。

    6.2.整体问答API请求

    package com.jasonjan.headnews.api;
    
    import com.jasonjan.headnews.bean.wenda.WendaArticleBean;
    import com.jasonjan.headnews.bean.wenda.WendaContentBean;
    import com.jasonjan.headnews.global.Constant;
    
    import io.reactivex.Observable;
    import okhttp3.ResponseBody;
    import retrofit2.http.Field;
    import retrofit2.http.FormUrlEncoded;
    import retrofit2.http.GET;
    import retrofit2.http.Headers;
    import retrofit2.http.POST;
    import retrofit2.http.Query;
    import retrofit2.http.Url;
    
    /**
     * Created by JasonJan on 2017/12/11.
     */
    
    public interface IMobileWendaApi {
        /**
         * 获取头条问答标题等信息
         * http://is.snssdk.com/wenda/v1/native/feedbrow/?category=question_and_answer&wd_version=5&count=20&max_behot_time=1495245397?iid=10344168417&device_id=36394312781
         *
         * @param maxBehotTime 时间轴
         */
        @GET("http://is.snssdk.com/wenda/v1/native/feedbrow/?iid=10344168417&device_id=36394312781&category=question_and_answer&wd_version=5&count=20&aid=13")
        Observable<WendaArticleBean> getWendaArticle(
                @Query("max_behot_time") String maxBehotTime);
    
    
        /**
         * 获取头条问答优质回答
         * http://is.snssdk.com/wenda/v1/question/brow/?iid=10344168417&device_id=36394312781
         *
         * @param qid 问答ID
         */
        @POST("http://is.snssdk.com/wenda/v1/question/brow/?iid=10344168417&device_id=36394312781")
        @FormUrlEncoded
        Observable<WendaContentBean> getWendaNiceContent(@Field("qid") String qid);
    
    
        /**
         * 获取头条问答优质回答(加载更多)
         * http://is.snssdk.com/wenda/v1/question/loadmore/?iid=10344168417&device_id=36394312781
         *
         * @param qid    问答ID
         * @param offset 偏移量
         */
        @POST("http://is.snssdk.com/wenda/v1/question/loadmore/?iid=10344168417&device_id=36394312781")
        @FormUrlEncoded
        Observable<WendaContentBean> getWendaNiceContentLoadMore(
                @Field("qid") String qid,
                @Field("offset") int offset);
    
        /**
         * 获取头条问答普通回答
         * http://is.snssdk.com/wenda/v1/questionother/brow/?iid=10344168417&device_id=36394312781
         *
         * @param qid 问答ID
         */
        @POST("http://is.snssdk.com/wenda/v1/questionother/brow/?iid=10344168417&device_id=36394312781")
        @FormUrlEncoded
        Observable<WendaContentBean> getWendaNormalContent(@Field("qid") String qid);
    
        /**
         * 获取头条问答普通回答(加载更多)
         * http://is.snssdk.com/wenda/v1/questionother/loadmore/?iid=10344168417&device_id=36394312781
         *
         * @param qid    问答ID
         * @param offset 偏移量
         */
        @POST("http://is.snssdk.com/wenda/v1/questionother/loadmore/?iid=10344168417&device_id=36394312781")
        @FormUrlEncoded
        Observable<WendaContentBean> getWendaNormalContentLoadMore(
                @Field("qid") String qid,
                @Field("offset") int offset);
    
        /**
         * 获取头条问答回答正文
         */
        @GET
        @Headers("User-Agent:" + Constant.USER_AGENT_MOBILE)
        Observable<ResponseBody> getWendaAnsDetail(@Url String url);
    }


  • 相关阅读:
    php 链接不上 mysql数据库,不是扩展的问题,也不是数据库的问题
    php中magic_quotes_gpc的作用
    QuickSkin简单学习控制结构
    Xdebug调试PHP程序 (NetBeans)
    记录bind方法。。。和ajax二级联动
    自己写的php分页代码,喜欢的就看看,很实用的
    想去掉启动时的win7选择怎么办
    QuickSkin简单学习属性和方法
    【CDQ分治】P3810 【模板】三维偏序(陌上花开)
    LibraryBar、LibraryContainer的宽高设置
  • 原文地址:https://www.cnblogs.com/Jason-Jan/p/8275184.html
Copyright © 2011-2022 走看看