Android详情页+定位评论区

来源:互联网 发布:上海旋转餐厅知乎 编辑:程序博客网 时间:2024/06/15 07:16

Android详情页+定位评论区

App中不可避免的会有详情页的需求,其中详情页千变万化没有一点规律,这时候就要用到Webview了。文章有点长,可以直接翻目录找自己需要的部分。

这里写图片描述

首先放一张详情页的效果图。

结构呢是:

<ScrollView>    <LinearLayout>    </LinearLayout></ScrollView>

以上只有主题内容部分,不包括标题栏。
有人就要嗤之以鼻了,这么多内容的页面你这么简单的布局就搞定了?
没错,就他妈的这么简单!

  • 其实没那么简单

有句话说的好,你之所以看不见黑暗,是因为有人竭尽全力把黑暗挡在你看不见的地方,没错!这个LinearLayout就是竭尽全力把复杂挡在了代码里的ViewGroup
这里写图片描述(逃 。。。。

我们知道了重点在这个LinearLayout ,下面来看下他都有哪些孩子?

  • 辅助加载类 ArticleDetailView
package com.lerdong.toys52.details;import android.app.Activity;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.widget.LinearLayout;/** - Created by Lwang on 16/6/20. */public class ArticleDetailView {    private Activity mContext;    private LinearLayout linearLayout,llGroup;    private View product_detail,recomment_detail,comment_num,detail_zan,htmlPrase,pinglunEmpty,flowLayoutTag;    public ArticleDetailView(Activity context) {        mContext = context;        linearLayout = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.article_detail_view, null);        llGroup = (LinearLayout) linearLayout.findViewById(R.id.ll_group);        product_detail = LayoutInflater.from(mContext).inflate(R.layout.detail_product,null);        flowLayoutTag = LayoutInflater.from(mContext).inflate(R.layout.tag_flowlayout,null);        product_detail.setVisibility(View.GONE);        htmlPrase = LayoutInflater.from(mContext).inflate(R.layout.prase_html_content,null);        pinglunEmpty = LayoutInflater.from(mContext).inflate(R.layout.detail_pinglun_empty_view,null);        recomment_detail = LayoutInflater.from(mContext).inflate(R.layout.detail_recomment,null);        comment_num = LayoutInflater.from(mContext).inflate(R.layout.item_comment_num,null);        detail_zan = LayoutInflater.from(mContext).inflate(R.layout.detail_zan,null);    }    /**     * 赞     * @return     */    public View getDetail_zan() {        return detail_zan;    }    /**     * 商品详情     * @return     */    public View getProduct_detail() {        return product_detail;    }    /**     * 相关推荐     * @return     */    public View getRecomment_detail() {        return recomment_detail;    }    /**     * 评论     * @return     */    public View getComment_num() {        return comment_num;    }    /**     * html解析器,带标题     * @return     */    public View getHtmlPrase() {        return htmlPrase;    }    /**     * 标签     * @return     */    public View getFlowLayoutTag() {        return flowLayoutTag;    }    /**     * 评论为空时显示     * @return     */    public View getEmptyView() {        return pinglunEmpty;    }    public void destoryView() {        product_detail = null;        recomment_detail = null;        comment_num = null;        linearLayout = null;        mContext = null;        llGroup = null;    }}

可以看到辅助类(ArticleDetailView)中加载了所有需要用到的模块。
这些模块大都一通百通,所以咱们就看下咱们的重点评论区。

评论区

rlDetail为评论区的RecyclerView,很遗憾没有什么高深的东西,只是new出来 addView到LinearLayout里了。

 @Override    public void init() {        reminderDialog = new ReminderDialog(this);        DaggerArticleDetailComponents.builder().articleModule(new ArticleModule(this)).build().inject(this);//        mArticleDetailPresenter = new ArticleDetailPresenter(this);        initIncludeOperation();        rlDetail = new RecyclerView(this);        rlDetail.setBackgroundColor(getResources().getColor(R.color.white));        articleDetailAdapter = new ArticleDetailAdapter();        articleDetailAdapter.setTOYSOnItemClickListener(this);        articleDetailAdapter.setTOYSOnItemChildClicklistener(this);        rlDetail.setLayoutManager(new LinearLayoutManager(this));        rlDetail.setAdapter(articleDetailAdapter);        articleDetailAdapter.setHolderStausListenter(this);        mRecommentFragment = new ImageTextFragment();        mRecommentFragment.setFirstMarginGone(true);        mRecommentFragment.setiFollowListener(this);        mRecommentFragment.setInitListener(this);        mRecommentFragment.setRFLoadMoreListener(this);    }
  • 什么?你问我ScrollView嵌套RecyclerView会不会出现问题?

    很明确的回答你,会的。

  • 可能会出现什么问题?
    1、RecyclerView滑动失灵,没有那种飘逸灵动的感觉了。(惯性滑动)

 解决方案:自定义ScrollView重写onInterceptTouchEvent@Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        onTouchEvent(ev);        return super.onInterceptTouchEvent(ev);    }

2、RecyclerView显示不全(我是没有遇到)
解决方案:
这里写图片描述

接下来重点WebView

首先来看下web返回来的json数据

"content": "<p>有着“万物有灵”观念的日本人,基于现实的种种,创造了各种妖怪,其中唐伞小僧(からかさ小僧)由于频繁地在电影、动漫和画作中出现,可能也与伞是人们日常接触较多的物件的关系,总之这个妖怪是大众熟悉的一位。</p><p><img src=\"http://img3.52toys.com/e609debfd7e0b058dce85b89e0db1d7b\" /></p><p style=\"text-align: center;\">水木茂笔下的唐伞小僧</p><p style=\"text-align: left;\">唐伞小僧是日本神话传说中的一种妖怪,属于付丧神的一种。传说中,它是油纸伞放置100年后变化而成的,特点是单眼、吐舌、单脚,且通常穿着下驮。<br/></p><p style=\"text-align: left;\"><img src=\"http://img3.52toys.com/1393e3813c5037ed6b1715409949b7ba\" /></p><p style=\"text-align: center;\">藤子·F·不二雄笔下的唐伞小僧</p><p style=\"text-align: left;\">唐伞小僧的形象并非一成不变的,也有两只手和两只腿的造型,只要基本造型没有脱离“伞”,大多归为唐伞小僧的词条下。<br/></p><p style=\"text-align: center;\"><img src=\"http://img3.52toys.com/75771e321ed220bc3a68ddbff06275fc\" />歌川芳員『百種怪談妖物双六』里的伞妖怪“一本足”</p><p><img src=\"http://img3.52toys.com/002c4a5f46ffada9f9b1a49d860e72ba\" /></p><p style=\"text-align: center;\">狩野宴信『百鬼夜行図巻』里的伞妖怪“二本足”</p><p style=\"text-align: center;\"><img src=\"http://img3.52toys.com/933604495de5999980c9574dfac46c43\" />歌舞伎演员是单腿扮演唐伞小僧的</p><p>上图歌舞伎演员尾上菊五郎扮演的唐伞小僧,和我最近收藏的一款搪胶玩具Karakasa Tattoo Man形象完全一样,制作方日本Secret Base应该参考这个演员的扮相。</p><p><img src=\"http://img3.52toys.com/4627ea3e355553276deef564421e4adc\" />第一次看到Karakasa Tattoo Man就非常喜欢这个造型,只是对于中国玩家来说,这个玩具不太容易买到。Secret Base基于这个造型,已经将其平台玩具化,推出了数款配色。其中有一款是夜光的版本,我对夜光材质的玩具向来是很喜欢的,而且夜光这个概念本身也很适合妖怪,所以就更想要了,只是遗憾的是这个版本只在美国发售。机缘巧合之下,一位美国好友帮我购入了。下面是这个夜光版本的实物照片:</p><p><img src=\"http://img3.52toys.com/c2d7e6187d695a9a46e5f15dff059b3f\" /></p><p>夜光材质的绝妙应用,把玩具烘托出一阵萌萌的鬼气。<br/><img src=\"http://img3.52toys.com/b1046a95a9d993a493b0882125bd93f3\" /></p><p>面部涂装是我们熟悉的歌舞伎演员形象。<br/><img src=\"http://img3.52toys.com/5ad69422135272bad99d6d9f490101b6\" /></p><p>左右胳膊和腿部都有非常精细的纹身,不过要非常小心避免摩擦和刺碰,导致纹身受损。<br/><img src=\"http://img3.52toys.com/969e9a5b751506c6a8fa13834b47bcdc\" /></p><p>没什么可动关节,但胜在造型亮眼,非常适合在书房中陈列。</p><p><img src=\"http://img3.52toys.com/2f9c1bb2d258559dfe49ccabb8f6a6fa\" /></p><p>这个玩具如果放上一百年,也会成精的吧?</p>",

可以看到content字段里有成片成片的html标签

  • 配置WebView
    提醒一句,关闭硬件加速。然后找个你喜欢的位置addView到LinearLayout中就行了
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    private void settingWebView() {        wvWeb.setWebViewClient(new MyWebViewClient());        wvWeb.setWebChromeClient(new WebChromeClient());        wvWeb.getSettings().setPluginState(WebSettings.PluginState.ON);        wvWeb.getSettings().setUseWideViewPort(true);        wvWeb.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);        wvWeb.getSettings().setBuiltInZoomControls(true);        wvWeb.getSettings().setSupportZoom(true);        wvWeb.getSettings().setJavaScriptCanOpenWindowsAutomatically(                true);        wvWeb.getSettings().setAllowFileAccess(true);        wvWeb.getSettings().setDomStorageEnabled(true);        wvWeb.getSettings().setDefaultTextEncodingName("UTF-8");        wvWeb.getSettings().setAppCacheEnabled(true);        wvWeb.getSettings().setLoadWithOverviewMode(true);        wvWeb.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);        wvWeb.getSettings().setJavaScriptEnabled(true);        wvWeb.addJavascriptInterface(new JavaScriptObject(ArticleDetailActivity.this), "toys52");//        wvWeb.setLayerType(View.LAYER_TYPE_HARDWARE, null);        wvWeb.getSettings().setBlockNetworkImage(true);        //注释掉,解决查看图文详情会崩溃的问题//        wvWeb.setTransitionGroup(true);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)            wvWeb.getSettings().setDisplayZoomControls(false);        if (Build.VERSION.SDK_INT >= 19) {            wvWeb.getSettings().setLoadsImagesAutomatically(true);        } else {            wvWeb.getSettings().setLoadsImagesAutomatically(false);        }    }
  • WebView插入之后就是喜闻乐见塞数据了。
 wvWeb.loadDataWithBaseURL(null, getHtmlData(content), "text/html", "utf-8", null);
public String getHtmlData(String content) {        TLog.e("webContent", "content:" + content);        String htmlData = "<html>\n" +                "<head>\n" +                "<meta charset=\"UTF-8\">" +                "<link rel=\"stylesheet\" href=\"file:///android_asset/common.css\"/>\n" +                "<link rel=\"stylesheet\" href=\"file:///android_asset/mobile.css\"/>\n" +                "<link rel=\"stylesheet\" href=\"file:///android_asset/bootstrap.min.css\"/>\n" +                "<script src=\"file:///android_asset/base.js\"></script>" +                "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n" +                "<meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width\">" +                "<style type=\"text/css\">\n" +                ".detail iframe{" +                "width: 100%;" +                "}" +                "</style>\n" +                "</head>\n" +                "<body>\n" +                "<div class=\"detail\">\n" +                content +                "</div>\n" +                "</body>\n" +                "</html>";        return htmlData;    }

html里引用了三个css文件,这些是从我司前端大大哪里搞来的,主要是控制图片,视频,文字大小等等的。
Js文件呢是用来监听WebView中图片加载完成的,之后在调用Android方法跳转评论区。晚些会把css文件和js文件上传。

详情页搞定。

跳转评论区

首先要知晓一点,android所有的滑动都是移动view来完成的,所以,我们要定位到评论区需要攻克的问题就是知道评论区View在ViewGroup中的位置

这里写图片描述

介绍一个方法。
getLocationInWindow(int[]) ,计算该视图在它所在的widnow的坐标x,y值,//获取在整个窗口内的绝对坐标
顺着思路来讲我只要获取到评论区在window中的位置和ScrollView在window中的位置就可以确定我要ScrollTo到何处了。

 /**     * 定位到评论区     */    private void goCommentLocation() {        needLocation = false;        new Handler().postDelayed(new Runnable() {            @Override            public void run() {                if(comment_num != null && mEasyScroll != null) {                    int[] comment_numxy = new int[2];                    int[] easyScrollxy = new int[2];                    comment_num.getLocationInWindow(comment_numxy);                    mEasyScroll.getLocationInWindow(easyScrollxy);                    mEasyScroll.smoothScrollTo(0, comment_numxy[1] - easyScrollxy[1]);                }            }        },postTime);    }

ScrollView到window定位的高正好是状态栏的高度,所以我们用评论区的高减去ScrollView的高就是我们要跳转的高度数值。

  • scrollBy,scrollTo和smoothScrollTo

    scrollBy是根据在上一个点的基础上+x, 移动后坐标为x+x1,y+y1
    scrollTo是移动到x1,y1上,移动后坐标为x1,y1
    smoothScrollTo 基本与scrollTo相同,不同点scrollTo没有动画,而smoothScrollTo平滑移动到目标点上。

什么时候跳转?

WebView加载多图卡顿崩溃?

当然是在整个WebView加载完成之后跳转了,但是还会有一个问题,那就是,WebView一次性加载很多张图片会直接卡到崩溃。
解决办法:wvWeb.getSettings().setBlockNetworkImage(false);
WebView加载数据的时候阻塞图片不要加载,等文字内容全部解析完毕,再wvWeb.getSettings().setBlockNetworkImage(true);,这样就会陆续开始加载图片。提示:onPageFinished

js监听图片加载完毕,回调Android跳转评论区
window.onload = function() {     var imgList = document.querySelectorAll('img');     var imgNum = imgList.length;     for(var i in imgList) {        imgList[i].onload = function(){          imgNum--;          if(imgNum == 0){             toys52.fun1FromAndroid();          }      };     } }
0 0
原创粉丝点击