1.效果预览

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

  TouTiao开源项目 分析笔记20 问答详情

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

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

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

 

 

 

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:andro>
    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 + "\n" + 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

  预览图片:

  TouTiao开源项目 分析笔记20 问答详情

相关文章:

  • 2021-09-17
  • 2022-01-04
  • 2021-11-26
  • 2022-01-14
  • 2021-11-15
  • 2021-12-11
  • 2021-07-29
  • 2021-12-25
猜你喜欢
  • 2022-01-12
  • 2021-08-23
  • 2021-08-26
  • 2022-03-06
  • 2022-02-18
  • 2021-10-21
  • 2021-09-04
相关资源
相似解决方案