android:使用TextView展示H5文本(含關(guān)鍵字點(diǎn)擊和圖片)

一、需求描述

使用TextView展示H5文本,文本中包含關(guān)鍵詞和圖片,在H5文本中只有關(guān)鍵詞會(huì)標(biāo)紅,在TextView中展示出來的關(guān)鍵詞需要加點(diǎn)擊事件。

具體如下圖:


使用TextView展示H5文本

二、需求分析——主要知識(shí)點(diǎn)

(1)、使用SpannableString

因H5文本中包含超鏈接和圖片,而且我們要使用TextView展示,那就必須使用SpannableString。將H5文本格式化成Spanned之后再轉(zhuǎn)成SpannableString,然后添加 ClickSpan 實(shí)現(xiàn)點(diǎn)擊事件

(2)、如何解析H5文本獲取全部關(guān)鍵詞?

需求描述中有說明:在H5文本中只有關(guān)鍵詞會(huì)標(biāo)紅,所以我們可以根據(jù)<font> 節(jié)點(diǎn)獲取全部的關(guān)鍵詞,獲取之后存儲(chǔ)在set中實(shí)現(xiàn)關(guān)鍵詞去重。

解析H5文本的時(shí)候我們可以自己去解析,也可以直接使用 jsoup 庫

jsoup 是一個(gè)開源的H5文本解析庫,文中使用的是jsoup庫。
添加依賴的時(shí)候,直接在 ProjectStructure——Dependences中搜索添加即可; 或者直接在 gradle文件中添加compile 'org.jsoup:jsoup:1.10.3'

(3)、如何展示圖片?

使用 Html.fromHtml(str , ImageGetter , tagHandler) 方法格式化H5 文本時(shí),ImageGetter 可以實(shí)現(xiàn)圖片的加載。由于圖片加載是耗時(shí)操作,需要將此代碼放置在線程中,防止主線程阻塞。Html.fromHtml(str) 方法不支持圖片的展示。

(4)、如何給所有關(guān)鍵詞加點(diǎn)擊事件?

加點(diǎn)擊事件的時(shí)候無疑要使用 ClickSpan, 前面我們也已經(jīng)獲取到了全部關(guān)鍵詞,而 setClickSpan 的時(shí)候需要用到關(guān)鍵詞的索引,那么接下來我們就需要遍歷獲取關(guān)鍵詞的索引位置。

遍歷某一個(gè)關(guān)鍵詞的時(shí)候,我們會(huì)獲取到起始索引,根據(jù)起始索引又能得到結(jié)束索引。獲取到該關(guān)鍵詞第一次出現(xiàn)時(shí)的索引之后,我們需要將字符串進(jìn)行截取,在截取之后的字符串中繼續(xù)查找該關(guān)鍵詞出現(xiàn)的位置,這樣得到的位置是在截取之后的字符串中的位置,我們還要得到關(guān)鍵詞在原始字符串中的位置,然后,依次類推,直到返回的索引為-1 —— -1表示后面的文本中沒有該關(guān)鍵詞了,才去遍歷下一個(gè)關(guān)鍵詞。

截取的目的是為了找出某個(gè)關(guān)鍵詞所有的出現(xiàn)位置。

所謂原始字符串,這里指的是 Html.fromHtml() 格式化之后構(gòu)造的SpannableString。

(5)、文本的滾動(dòng)處理

TextView 本身具有滾動(dòng)屬性,但是在不同的手機(jī)上得到的效果不一致,為了方便控制滾動(dòng)效果,外層使用ScrollView包裹。

三、具體代碼實(shí)現(xiàn):

(1)、activity_showh5text.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>

    </data>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">


            <TextView
                android:id="@+id/tv_showComplexH5Text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

    </ScrollView>

</layout>

(2)、ShowH5TextActivity.java

代碼中的H5文本串范例由于在AS中多次格式化,所以出現(xiàn)了很多 +“” ,不影響正常效果。


/**
 * 作者:CnPeng
 * <p>
 * 時(shí)間:2017/10/20:下午3:47
 * <p>
 * 說明:在TextView中展示H5文本,在H5中關(guān)鍵字標(biāo)紅,其他文本不設(shè)置字體。在TextView中需要給關(guān)鍵字增加點(diǎn)擊事件,同時(shí)TextView中還需要展示出H5中指定的圖片
 * <p>
 * ——使用了數(shù)據(jù)綁定
 * ——在解析這個(gè) H5 文本串時(shí)使用的是 jsoup 庫。
 * ——雖然TextView本身具有滾動(dòng)屬性,但是在不同手機(jī)上表現(xiàn)不一樣:華為Che1-L20上滑動(dòng)不流暢,魅族m3-note上滑動(dòng)后會(huì)自動(dòng)回到頂部。所以用ScrollView 包裹
 * ——jsoup中沒有找到關(guān)于根據(jù)TAG和節(jié)點(diǎn)文本獲取屬性值的方法,所以無法通過代碼去獲取font節(jié)點(diǎn)中的屬性值。(確實(shí)有必要的話可以考慮自己解析h5文本)
 * ——使用線程是為了保證圖片能加載處理,加載圖片是耗時(shí)操作,不用子線程的話圖片可能會(huì)加載不出來
 */

public class ShowH5TextActivity extends AppCompatActivity {
    String H5String = "<html>\n" + " <head></head>\n" + " <body>\n" + "  <p style=\"text-indent: 2em;\"><span " + 
            "style=\"font-family: 宋體, SimSun; font-size: 16px;\">周三下午公布的<font " + 
            "color=\"#FF0000\">英國</font>5月失業(yè)率、英國5月失業(yè)金申請(qǐng)人數(shù)、英國4月三個(gè)月ILO失業(yè)率顯示,英國4月三個(gè)月剔除紅利的平均工資年率刷新2015年1月以來新低。英國2-4月連續(xù)3" 
            + "個(gè)月失業(yè)率為1975年以來最低,英國就業(yè)市場連續(xù)3" + 
            "個(gè)月保持穩(wěn)健,但薪資增速進(jìn)一步放緩,料將對(duì)內(nèi)需產(chǎn)生負(fù)面影響,為英國經(jīng)濟(jì)增長預(yù)期增添擔(dān)憂情緒。英國國家統(tǒng)計(jì)局表示薪資數(shù)據(jù)將改善小型企業(yè)的薪資策略,對(duì)薪資水平產(chǎn)生下行影響。</span></p>\n" + "  " +
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "<p><br " + "/></p>\n" + "  " + "<p" + "" + " " + 
            "style=\"text-indent: " + "2em;" + "\"><span " + "" + "" + "" + "style=\"font-family:" + " " + "宋體, " + 
            "" + "SimSun; " + "font-size: " + "16px;" + "\">英國前首相<font " + 
            "color=\"#FF000\">卡梅倫</font>表示現(xiàn)任首相特雷莎&middot;" + 
            "梅應(yīng)采取“軟脫歐”,并表示她應(yīng)該與工黨等反對(duì)派進(jìn)行進(jìn)一步交涉,與各黨派進(jìn)行更廣泛的磋商以達(dá)成更多共識(shí)。認(rèn)為“軟脫歐”或許會(huì)面臨更大壓力,并表示議會(huì)現(xiàn)在應(yīng)盡快面對(duì)這個(gè)問題。同時(shí)<font " + 
            "color=\"#FF000\">卡梅倫</font>還對(duì)特蕾莎&middot;梅表示了支持。</span></p>\n" + "  <p><br /></p>\n" + "  <p " + 
            "style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, SimSun; font-size: 16px;" + 
            "\">據(jù)華爾街日?qǐng)?bào),MacroPolicy" + " Perspectives " + "LLC調(diào)查顯示約50%的受訪者表示,股市沒有對(duì)美聯(lián)儲(chǔ)的計(jì)劃做出反應(yīng),42" + 
            "%的受訪者認(rèn)為信用債市場也沒有做出反應(yīng)。幾乎沒有受訪者認(rèn)為美聯(lián)儲(chǔ)的計(jì)劃在任何市場得到了充分的消化。這表明如果美聯(lián)儲(chǔ)在啟動(dòng)這項(xiàng)計(jì)劃前沒有與市場有效溝通,將可能引發(fā)不利的市場變動(dòng)。</span></p>\n" +
            "  <p><br /></p>\n" + "  <p style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, SimSun; " + 
            "font-size:" + " 16px;\">北京時(shí)間本周四凌晨2點(diǎn)美聯(lián)儲(chǔ)將公布最新利率決議及<font " + 
            "color=\"#FF0000\">政策聲明</font>,預(yù)計(jì)美元在經(jīng)歷會(huì)議后將面臨走軟風(fēng)險(xiǎn);市場廣泛預(yù)期本次會(huì)議將加息25個(gè)基點(diǎn)至1.00%-1.25%;然而,F(xiàn)OMC有可能在此次聲明中降低核心PCE" 
            + "通脹預(yù)期,長期聯(lián)邦利率中值預(yù)期也有降低的可能性,這將對(duì)加息造成壓力;此外,預(yù)計(jì)本次會(huì)議將對(duì)縮減資產(chǎn)負(fù)債表計(jì)劃有所置評(píng)。</span></p>\n" + "  <p><br /></p>\n" + "  "
            + "<p " + "style=\"text-indent: 2em;\"><img src=\"http://www.gfxa" + "" + "" + "" + "" + "" + "" + "" + 
            "" + ".com/upload/image/20170614/6363305821523119573565195.png\" title=\"\" /></p>\n" + "  <p " + 
            "style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, SimSun; font-size: 16px;" + 
            "\">支撐:1260——1255——1247 阻力:1273——1281</span></p>\n" + "  <p style=\"text-indent: 2em;\"><span " + 
            "style=\"font-family: 宋體, SimSun; font-size: 16px;\">交易策略:現(xiàn)貨黃金現(xiàn)價(jià)1268.30,日內(nèi)交易建議如下:</span></p>\n" + "  <p "
            + "style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, SimSun; font-size: 16px;\">A:北京時(shí)間22:00之前," 
            + "現(xiàn)貨黃金上行至1274附近時(shí)四十分之一倉位做空,止損設(shè)1279,目標(biāo)下看至1268/1265區(qū)間止盈。持倉階段,現(xiàn)貨黃金下破1271后,建議將止損位下移至1274附近。持倉階段,浮盈大于6" + 
            "美金時(shí)建議隨機(jī)止盈。鑒于美聯(lián)儲(chǔ)利率決議影響的不確定性,此交易如觸發(fā),北京時(shí)間6月15日01:00之前建議擇機(jī)離場。</span></p>\n" + "  <p style=\"text-indent: " +
            "2em;\"><span style=\"font-family: 宋體, SimSun; font-size: 16px;\">B:北京時(shí)間6月15日07:00之前," + 
            "現(xiàn)貨黃金下行至1260和1253附近時(shí)分別以五十分之一倉位做多,止損統(tǒng)一設(shè)1245,目標(biāo)依次上看1268—1273—1281—1288附近。持倉階段,浮盈大于5" + 
            "美金時(shí),建議將止損位上移至成本位。持倉階段,浮盈大于25美金時(shí)建議隨機(jī)止盈。</span></p>\n" + "  <p><br /></p>\n" + " <p style=\"text-indent: "
            + "2em;\"><span style=\"font-family: 宋體, SimSun; font-size: 16px;\">美元兌日元</span></p>\n" + "  <p " + 
            "style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, SimSun; font-size: 16px;" + 
            "\">美元兌日元</span></p>\n" + "  <p style=\"text-indent: 2em;\"><img src=\"http://www.gfxa" + "" + "" + "" + 
            ".com/upload/image/20170614/6363305822435631122386267.png\" title=\"\" /></p>\n" + "  <p " + 
            "style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, SimSun; font-size: 16px;\">支撐109.90 " + 
            "阻力110.40-110.80</span></p>\n" + "  <p style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, SimSun;" +
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + " " + "font-size: " + "16px;" + 
            "\">交易策略:美元兌日元,現(xiàn)價(jià)報(bào)111.20。明日凌晨有美聯(lián)儲(chǔ)議息會(huì)議,注意風(fēng)險(xiǎn)。加息概率極高,但是美元走勢(shì)依舊疲軟,不排除出現(xiàn)美元空頭回補(bǔ)的現(xiàn)象。日內(nèi)交易建議如下:</span" + "></p" + 
            "" + ">\n" + "" + "  " + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 
            "<p " + "style=\"text-indent: " + "2em;" + "\"><span " + "style=\"font-family: " + "宋體, " + "SimSun;" + 
            "" + " " + "font-size: " + "16px;" + "\">A: " + "突破110.40做多,止損110.30,止盈110.77</span></p>\n" + "  " + "<p " +
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "style=\"text-indent: 2em;" + 
            "\"><span " + "" + "style=\"font-family:" + " 宋體, " + "" + "SimSun; " + "font-size: " + "16px;" + "\">B: " +
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 
            "" + "應(yīng)對(duì)加息:限價(jià)賣出掛單于110.80,止損111.20,止盈110.40</span></p>\n" + "" + "  " + "<p><br " + "/></p>\n" + " " + " "
            + "<p " + "style=\"text-indent: " + "2em;\"><span " + "style=\"font-family: 宋體, " + "SimSun; " + 
            "font-size: 16px;" + "\">英鎊兌美元</span></p>\n" + "  <p " + "style=\"text-indent: 2em;" + "\"><img" + " " + 
            "src=\"http://www.gfxa" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" +
            "" + "" + "" + "" + "" + "" + "" + "" + ".com/upload/image/20170614/6363305823223140971492124.png\" " + 
            "title=\"\" " + "/><span" + " " + "style=\"font-family: 宋體, " + "SimSun; font-size: 16px;\">&nbsp; &nbsp;" +
            "" + "" + "" + "" + "" + "" + "" + "" + " &nbsp; &nbsp;" + " " + "&nbsp; &nbsp;" + " " + "" + "" + "" + 
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "&nbsp; &nbsp; &nbsp; &nbsp; " + "&nbsp;" + "" +
            " " + "&nbsp; " + "&nbsp; " + "" + "" + "&nbsp; " + "&nbsp; " + "&nbsp;" + " " + "&nbsp; " + "&nbsp; " + 
            "" + "&nbsp;" + "</span></p>\n" + "" + "" + "  <p " + "" + "style=\"text-indent: 2em;" + "\"><span" + " "
            + "style=\"font-family: " + "宋體, " + "" + "SimSun; " + "font-size: " + "16px;" + "\">支撐1.2673-1.2600 " + 
            "阻力1.1287-1.2828</span></p>\n" + "  " + "<p" + " " + "style=\"text-indent:" + " " + "" + "" + "" + "" + 
            "" + "" + "" + "" + "" + "" + "" + "" + "" + "2em;" + "\"><span " + "" + "" + "style=\"font-family: " + 
            "宋體, " + "SimSun;" + " " + "font-size: " + "" + "16px;" + 
            "\">交易策略:如圖歐元兌美元四小時(shí)圖所示,現(xiàn)價(jià)報(bào)1.2753,歐元軸心點(diǎn)為1.2714,中樞區(qū)間為1.2698—1.2730" + ",日內(nèi)交易建議如下:</span></p>\n" + "  " + 
            "<p " + "style=\"text-indent: 2em;\"><span style=\"font-family: 宋體, " + "SimSun; font-size: " + "16px;" +
            "\">A:建議1.2730賣出英鎊對(duì)美元,止損1.2787,止盈1.2673.</span></p>\n" + "  <p " + "style=\"text-indent: 2em;" + 
            "\"><span " + "style=\"font-family: 宋體, SimSun; font-size: 16px;" + 
            "\">(該建議以10000美金下0.5手為基準(zhǔn),參照可自行換算。請(qǐng)投資者控制好倉位,嚴(yán)格止損。)</span></p>\n" + "  <p><br /></p>\n" + " </body>\n" + 
            "</html>";

    private ActivityShowh5textBinding binding;
    private String                    tempSplitedStr;       //臨時(shí)切割得到的字符串

    private final int FLAG_CONVERT_H5TEXT_OVER = 1;  //將H5轉(zhuǎn)換成spanableString 完畢
    private final int MODE_INTRINSIC           = 0x001; //根據(jù)圖片的原始大小進(jìn)行展示
    private final int MODE_BASE_WINDOW_WITH    = 0x002; //與屏幕等寬(保持寬高比)

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (null != msg && msg.what == FLAG_CONVERT_H5TEXT_OVER) {
                binding.tvShowComplexH5Text.setText((SpannableString) msg.obj);
                //設(shè)置該句使文本的超連接起作用,不設(shè)置該句代碼,點(diǎn)擊事件不生效?。?!
                binding.tvShowComplexH5Text.setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
    };


    @Override
    public void onCreate(
            @Nullable
                    Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_showh5text);
        getAndSetStrToTextView();
    }

    /**
     * 獲取并設(shè)置字符串到TextView
     */
    private void getAndSetStrToTextView() {
        final HashSet<String> keyWordsSet = getAllKeyWords();

        new Thread(new Runnable() {     //之所以放在線程中完成H5轉(zhuǎn) SpannableStirng ,是為了加載H5的圖片
            @Override
            public void run() {
                Spanned normalStr = convertH5TextToSpanned();
                SpannableString spannableStr = new SpannableString(normalStr);  //最終要展示的字符串

                tempSplitedStr = spannableStr.toString();      //全局變量,賦初值

                for (String keyStr : keyWordsSet) { //為所有關(guān)鍵字增加點(diǎn)擊事件
                    findKeyAndSetEvent(spannableStr, tempSplitedStr, keyStr, 0);
                }

                Message msg = handler.obtainMessage();
                msg.what = FLAG_CONVERT_H5TEXT_OVER;
                msg.obj = spannableStr;
                handler.sendMessage(msg);
            }
        }).start();
    }


    /**
     * 將H5字符串轉(zhuǎn)換成Spanned字符串保證圖片的顯示。
     */
    private Spanned convertH5TextToSpanned() {
        return Html.fromHtml(H5String, new Html.ImageGetter() {
            @Override
            public Drawable getDrawable(String url) {
                InputStream is;
                try {
                    is = (InputStream) new URL(url).getContent();
                    Drawable d = Drawable.createFromStream(is, "src");

                    setDrawableBounds(d, MODE_BASE_WINDOW_WITH);  //設(shè)置圖片區(qū)域

                    is.close();
                    return d;
                } catch (Exception e) {
                    return null;
                }
            }
        }, null);
    }

    /**
     * 設(shè)置圖片的區(qū)域,必須設(shè)置,否則圖片不展示
     *
     * @param d                圖片對(duì)象
     * @param withOrHeightMode 寬高模式
     */
    private void setDrawableBounds(Drawable d, int withOrHeightMode) {
        switch (withOrHeightMode) {
            case MODE_INTRINSIC:    //根據(jù)原圖大小進(jìn)行展示
                d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
                break;
            case MODE_BASE_WINDOW_WITH: //與屏幕等寬
                WindowManager wm = getWindowManager();
                int wmWidth = wm.getDefaultDisplay().getWidth();
                int picWidth = d.getIntrinsicWidth();
                int picHeight = d.getIntrinsicHeight();

                picHeight = (int) (picHeight * (wmWidth / picWidth * 1.0));

                d.setBounds(0, 0, wmWidth, picHeight);
        }
    }

    /**
     * 找出單個(gè)關(guān)鍵字每一次出現(xiàn)的位置并為其增加點(diǎn)擊事件
     *
     * @param tempSplitedStr 被切割后的新字符串
     * @param keyStr         關(guān)鍵字
     * @param preEndIndex    關(guān)鍵詞上一次出現(xiàn)時(shí)的結(jié)束索引/關(guān)鍵字本次在原始字符串中的結(jié)束索引
     */
    private void findKeyAndSetEvent(SpannableString spannableString, String tempSplitedStr, final String keyStr,
                                    int preEndIndex) {
        final int startIndex = tempSplitedStr.indexOf(keyStr);     //起始索引
        if (startIndex != -1) {
            final int endIndex = startIndex + keyStr.length() - 1;    //終止索引,
            int startIndexInOgirinal = 0;

            if (preEndIndex == 0) {    //關(guān)鍵字第一次出現(xiàn)
                startIndexInOgirinal = startIndex;
                preEndIndex = endIndex;
            } else {      //關(guān)鍵字不是第一次出現(xiàn)
                startIndexInOgirinal = startIndex + preEndIndex + 1;    //加1 是因?yàn)榻厝〉淖址饕质菑?開始
                preEndIndex = startIndexInOgirinal + keyStr.length() - 1;   //減1 是因?yàn)槠鹗妓饕呀?jīng)占了一個(gè)索引
            }

            LogUtils.e("在臨時(shí)字符串中的位置:", startIndex + "/" + endIndex);
            LogUtils.e("原始字符串中的位置:", startIndexInOgirinal + "/" + preEndIndex);

            spannableString.setSpan(new ClickableSpan() {
                @Override
                public void onClick(View widget) {
                    //點(diǎn)擊事件彈窗+請(qǐng)求服務(wù)器數(shù)據(jù)
                    Toast.makeText(ShowH5TextActivity.this, "點(diǎn)我干嘛?關(guān)鍵字:" + keyStr, Toast.LENGTH_SHORT).show();
                }

                @Override
                public void updateDrawState(TextPaint ds) {
                    //super.updateDrawState(ds);
                    ds.setColor(Color.RED);      //更改超鏈接顏色(此顏色要與H5中關(guān)鍵字的 font 顏色一致)
                    ds.setUnderlineText(false);     //不展示下劃線
                }
            }, startIndexInOgirinal, preEndIndex + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            //}, startIndexInOgirinal, preEndIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);  //這樣的話,非第一次出現(xiàn)的只會(huì)將第一個(gè)字符加上超鏈接

            tempSplitedStr = tempSplitedStr.substring(endIndex + 1);  //截取字符串,+1 表示從關(guān)鍵詞后面截取,不含關(guān)鍵字;不加1 的話從關(guān)鍵詞最后一個(gè)字開始截取
            findKeyAndSetEvent(spannableString, tempSplitedStr, keyStr, preEndIndex);     //遞歸調(diào)用
        }
    }

    /**
     * 獲取關(guān)鍵字,并使用Set存儲(chǔ),實(shí)現(xiàn)去重
     */
    private HashSet<String> getAllKeyWords() {
        HashSet<String> keysSet = new HashSet<>();
        Document document = Jsoup.parse(H5String);
        Elements elementsList = document.getElementsByTag("font"); //在JSOUP中,Elements類繼承自ArrayList

        if (null != elementsList) {
            for (Element element : elementsList) {
                keysSet.add(element.text());
            }
        }

        return keysSet;
    }
}

四、附錄

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,322評(píng)論 0 17
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 47,147評(píng)論 22 665
  • 最近有一個(gè)需求:移動(dòng)端需要展示用戶在PC端做的筆記,而筆記內(nèi)容是富文本形式——有圖片,有文字,文字可以設(shè)置顏色、加...
    JsCoderr閱讀 1,348評(píng)論 0 3
  • 在育兒方面其實(shí)我內(nèi)心是比較焦慮的,最明顯的一點(diǎn)就是喜歡關(guān)注各種育兒公眾號(hào),各種啟蒙貼。但在這個(gè)信息爆炸時(shí)代,育兒育...
    大鵬不展翅閱讀 266評(píng)論 0 0
  • 跟他分手好久了快要兩個(gè)月,最近一直有聯(lián)系,對(duì)我來說他是不可替代的,即使分手了還是愛他,很矛盾的是分手后與其他男生聊...
    74700b0b3a63閱讀 295評(píng)論 0 1

友情鏈接更多精彩內(nèi)容