掃碼 項(xiàng)目總結(jié)-V1.3.0

好吧想际,其實(shí)V1.3.5 已經(jīng)在上個(gè)月下旬做完了,現(xiàn)在才來寫總結(jié)溪厘,但凡勤快點(diǎn)都不會(huì)拖到現(xiàn)在胡本,害呀。這里標(biāo)題是V1.3.0畸悬,但其實(shí)這個(gè)版本做出來沒有上線侧甫,直接上的V1.3.5。所以就一并總結(jié)了蹋宦。
V1.3相對(duì)于V1.2主要增加的功能就是創(chuàng)建二維碼收藏披粟,但其實(shí)關(guān)于創(chuàng)建二維碼的代碼很簡(jiǎn)單,本篇文章的主要內(nèi)容也不是單純的創(chuàng)建冷冗。下邊是本文的主要內(nèi)容:

V1.3.0總結(jié)

可以看到總結(jié)的點(diǎn)比較散守屉,隨便一個(gè)單獨(dú)拿出來都可以水一篇文章了,文章雖然水蒿辙,但都是干貨哈

一 . 單選框的定制和使用RadioGroup和RadioButton

我們知道谷歌提供了一個(gè)單選控件RadioButton拇泛,這個(gè)通常是需要和RadioGroup一起使用的。
多個(gè)RadioButton置于一個(gè)RadioGroup思灌,然后通過RadioGroup去控制其中的RadioButton俺叭。
RadioGroup是繼承于LinearLayout的,所以用起來也很順手习瑰。

1.布局

這里我需要的是三個(gè)橫向排布的單選框绪颖,所以布局如下:

            <RadioGroup
                android:id="@+id/wifi_encryption_radio"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginHorizontal="30dp"
                android:layout_marginVertical="10dp"
                android:orientation="horizontal"
                android:visibility="gone">

                <RadioButton
                    android:id="@+id/radio1"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@drawable/bg_radio"
                    android:button="@null"
                    android:gravity="center"
                    android:padding="8dp"
                    android:text="@string/WPA_WPA2"
                    android:textColor="@drawable/bg_radio_text"
                    android:textSize="15sp" />

                <RadioButton
                    android:id="@+id/radio2"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginHorizontal="10dp"
                    android:layout_weight="1"
                    android:background="@drawable/bg_radio"
                    android:button="@null"
                    android:gravity="center"
                    android:padding="8dp"
                    android:text="@string/WPE"
                    android:textColor="@drawable/bg_radio_text"
                    android:textSize="15sp" />

                <RadioButton
                    android:id="@+id/radio3"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@drawable/bg_radio"
                    android:button="@null"
                    android:gravity="center"
                    android:padding="8dp"
                    android:text="@string/no_encryption"
                    android:textColor="@drawable/bg_radio_text"
                    android:textSize="15sp" />
            </RadioGroup>

主要目的就是讓用戶選擇wifi加密方式
其實(shí)就是一個(gè)ViewGroup設(shè)置方向?yàn)闄M向后,排布幾個(gè)radiobutton,就這么簡(jiǎn)單柠横,當(dāng)然還有其他屬性上的設(shè)置窃款,等會(huì)慢慢講,現(xiàn)在給每個(gè)控件加上id就可以了

2.改變樣式

我們知道牍氛,原本的radio button是非常丑的晨继,就像這個(gè):


radio button

要是直接這么上去,產(chǎn)品和ui都要罵娘了搬俊,所以要設(shè)計(jì)radio button的樣式紊扬,就像這樣:

效果圖

接下來請(qǐng)參考上邊的布局代碼一起閱讀。
第一步
去掉radio button右邊的小圓點(diǎn)唉擂,這個(gè)非常簡(jiǎn)單:只需要一個(gè)屬性
android:button="@null"
當(dāng)然也可以通過這個(gè)屬性設(shè)置這個(gè)button的樣式餐屎,我們不需要就直接去掉。

第二步
設(shè)置選擇選中和未選中的邊框顏色
一個(gè)個(gè)來玩祟,邊框?qū)嶋H上就是背景腹缩,背景一般采用drawable來繪制,所以新建一個(gè)命名為bg_radio的selector drawable文件空扎,
不懂drawable的同學(xué)移步:http://www.reibang.com/p/f01b1af15a88
內(nèi)容如下:
android:background="@drawable/bg_radio"

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_checked="false"
        android:drawable="@drawable/bg_edit_text_normal" />
    <item
        android:state_checked="true"
        android:drawable="@drawable/bg_edit_text_focused" />
</selector>

具體的shape就不給了谭胚,其實(shí)這里的bg_edit_text_normal和bg_edit_text_focused饵史,就是一個(gè)圓角,1dp寬邊框的不同顏色的樣式。關(guān)鍵點(diǎn)其實(shí)的這里item對(duì)應(yīng)的state_checked屬性橙困,指定了選中和未選中應(yīng)該用什么樣式填物。
然后在radio button 中設(shè)置屬性:
android:background="@drawable/bg_radio"
第三步
設(shè)置選擇選中和未選中的字體顏色
同樣的步驟毛萌,新建一個(gè)命名為bg_radio_text的selector drawable文件损晤,
內(nèi)容如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="@color/theme_color" />
    <item android:state_checked="false" android:color="@color/gray_text" />
</selector>

最后設(shè)置radio button屬性:
android:textColor="@drawable/bg_radio_text"

現(xiàn)在樣式就改完了,感覺還行甫煞,接下來實(shí)現(xiàn)功能菇曲。

3.獲取選擇的內(nèi)容

我們要點(diǎn)擊使用時(shí),需要獲取一下當(dāng)前選了什么
非常簡(jiǎn)單抚吠,就使用radio group的一條屬性就可以了:

                when (wifi_encryption_radio.checkedRadioButtonId) {
                    R.id.radio1 -> {
                        encryption = "WPA"
                    }
                    R.id.radio2 -> {
                        encryption = "WPE"
                    }
                    R.id.radio3 -> {//沒有加密類型
                        password = ""
                        encryption = ""
                    }
                }
4.給定默認(rèn)值

本來radio group默認(rèn)是什么都不選的常潮,但是如果需要默認(rèn)選擇一個(gè),可以這么設(shè)置:

 //默認(rèn)選擇第一個(gè)
wifi_encryption_radio.check(R.id.radio1)
5.選擇監(jiān)聽

有的小伙伴又有需求了楷力,說之前獲取選擇內(nèi)容只是用戶最終選擇的結(jié)果喊式,但是我想要用戶每次選擇我都知道選了哪個(gè),怎么辦
這個(gè)時(shí)候設(shè)置給radio group設(shè)置一下選擇監(jiān)聽就可以了:

        wifi_encryption_radio.setOnCheckedChangeListener(object:RadioGroup.OnCheckedChangeListener{
            override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
                when (checkedId) {
                    R.id.radio1 -> {
                        
                    }
                    R.id.radio2 -> {
                        
                    }
                    R.id.radio3 -> {
                       
                    }
                }
            }
        })

二 . RecycleView統(tǒng)一修改所有item的布局

就像這個(gè)樣子:

效果圖

在點(diǎn)擊刪除后萧朝,原本的收藏按鈕消失岔留,取而代之的是刪除按鈕,這該怎么實(shí)現(xiàn)呢检柬?
非常簡(jiǎn)單:在adapter中添加一個(gè)全局變量isShowDeleteBtn一開始置為false
然后在onBindViewHolder方法中加入以下代碼:

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
......省略代碼

        if (isShowDeleteBtn) {
            holder.deleteBtn.visibility=View.VISIBLE
            holder.collectBtn.visibility=View.GONE
        } else {
            holder.deleteBtn.visibility=View.GONE
           holder.collectBtn.visibility=View.VISIBLE
    }

最后在需要改變布局的時(shí)候這樣做:

    fun changeDeleteLayout() {
        mAdapter.isShowDeleteBtn=! mAdapter.isShowDeleteBtn
        //item發(fā)生改變 重新繪制item布局
        mAdapter.notifyItemRangeChanged(0,mData.size)
    }

這里的notifyItemRangeChanged非常關(guān)鍵献联,它表示一定范圍內(nèi)item內(nèi)容修改,需要重新繪制。如果把范圍擴(kuò)大到全部里逆,則會(huì)重新繪制所有item进胯。
源碼在這里:感興趣可以看看注釋說明

        /**
         * Notify any registered observers that the <code>itemCount</code> items starting at
         * position <code>positionStart</code> have changed.
         * Equivalent to calling <code>notifyItemRangeChanged(position, itemCount, null);</code>.
         *
         * <p>This is an item change event, not a structural change event. It indicates that
         * any reflection of the data in the given position range is out of date and should
         * be updated. The items in the given range retain the same identity.</p>
         *
         * @param positionStart Position of the first item that has changed
         * @param itemCount Number of items that have changed
         *
         * @see #notifyItemChanged(int)
         */
        public final void notifyItemRangeChanged(int positionStart, int itemCount) {
            mObservable.notifyItemRangeChanged(positionStart, itemCount);
        }

在附贈(zèng)一個(gè)刪除item的效果,當(dāng)你從mData中移除了某一項(xiàng)后原押,
請(qǐng)調(diào)用notifyItemRemoved而不是notifyDataSetChanged

    fun removeItem(position: Int){
        mData.remove(mData[position])
        mAdapter.notifyItemRemoved(position)
    }

mAdapter.notifyItemRemoved(position)表示某個(gè)位置的內(nèi)容被移除了胁镐,這時(shí)會(huì)有動(dòng)畫效果體現(xiàn)出來(這個(gè)動(dòng)畫也可以自定義)

三 . 軟鍵盤

在我們程序中,難免會(huì)遇到使用輸入框诸衔,這個(gè)時(shí)候就會(huì)彈出軟鍵盤盯漂,那么關(guān)于軟鍵盤和輸入框的一些注意點(diǎn)我就寫在這了。

1.軟鍵盤的彈出方式

彈出方式分別是:鍵盤覆蓋頁面笨农,鍵盤擠占頁面布局就缆,鍵盤頂起整個(gè)頁面(不覆蓋,不擠占)磁餐,自定義方式(監(jiān)聽根布局Layout 的Size改變违崇,獲得軟鍵盤高度阿弃,動(dòng)態(tài)修改頁面)诊霹,等等
參考:https://www.cnblogs.com/jerehedu/p/4194125.html
處理方式:項(xiàng)目的AndroidManifest.xml文件中界面對(duì)應(yīng)的<activity>里修改屬性
例子:這會(huì)使屏幕整體上移

android:windowSoftInputMode="stateVisible|adjustResize" 

關(guān)于windowSoftInputMode的一些知識(shí)點(diǎn):
activity主窗口與軟鍵盤的交互模式,可以用來避免輸入法面板遮擋問題渣淳。
它的設(shè)置必須是下面列表中的一個(gè)值脾还,或一個(gè)”state…”值加一個(gè)”adjust…”值的組合:(值之間采用 | 分開)
列表:
各值的含義:

【A】stateUnspecified:軟鍵盤的狀態(tài)并沒有指定,系統(tǒng)將選擇一個(gè)合適的狀態(tài)或依賴于主題的設(shè)置

【B】stateUnchanged:當(dāng)這個(gè)activity出現(xiàn)時(shí)入愧,軟鍵盤將一直保持在上一個(gè)activity里的狀態(tài)鄙漏,無論是隱藏還是顯示

【C】stateHidden:用戶選擇activity時(shí),軟鍵盤總是被隱藏

【D】stateAlwaysHidden:當(dāng)該Activity主窗口獲取焦點(diǎn)時(shí)棺蛛,軟鍵盤也總是被隱藏的

【E】stateVisible:軟鍵盤通常是可見的

【F】stateAlwaysVisible:用戶選擇activity時(shí)怔蚌,軟鍵盤總是顯示的狀態(tài)

【G】adjustUnspecified:默認(rèn)設(shè)置,通常由系統(tǒng)自行決定是隱藏還是顯示

【H】adjustResize:該Activity總是調(diào)整屏幕的大小以便留出軟鍵盤的空間

【I】adjustPan:當(dāng)前窗口的內(nèi)容將自動(dòng)移動(dòng)以便當(dāng)前焦點(diǎn)從不被鍵盤覆蓋和用戶能總是看到輸入內(nèi)容的部分

2.軟鍵盤彈起收回的監(jiān)聽

Android系統(tǒng)并沒有直接提供監(jiān)聽鍵盤彈起收回的方法旁赊,只能通過一些特殊的方式來監(jiān)聽桦踊。比如下邊這種,通過監(jiān)聽Layout高度的改變终畅,來確認(rèn)鍵盤是否彈起收回籍胯。有一個(gè)工具類如下:


import android.app.Activity
import android.graphics.Rect
import android.view.View
import android.view.ViewTreeObserver


/**
 * Created by liujinhua on 15/10/25.
 */
class SoftKeyBoardListener(activity: Activity) {
    private val rootView: View//activity的根視圖
    var rootViewVisibleHeight: Int //紀(jì)錄根視圖的顯示高度

    private var onSoftKeyBoardChangeListener: OnSoftKeyBoardChangeListener? = null
    private fun setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener: OnSoftKeyBoardChangeListener) {
        this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener
    }

    interface OnSoftKeyBoardChangeListener {
        fun keyBoardShow(height: Int)
        fun keyBoardHide(height: Int)
    }

    companion object {
        fun setListener(
            activity: Activity?,
            onSoftKeyBoardChangeListener: OnSoftKeyBoardChangeListener?
        ) {
            val softKeyBoardListener = activity?.let { SoftKeyBoardListener(it) }
            if (onSoftKeyBoardChangeListener != null) {
                softKeyBoardListener!!.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener)
            }
        }
    }

    init {
        //獲取activity的根視圖
        rootView = activity.getWindow().getDecorView()
        val r = Rect()
        rootView.getWindowVisibleDisplayFrame(r)
        rootViewVisibleHeight = r.height()
        //監(jiān)聽視圖樹中全局布局發(fā)生改變或者視圖樹中的某個(gè)視圖的可視狀態(tài)發(fā)生改變
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                //獲取當(dāng)前根視圖在屏幕上顯示的大小
                val r = Rect()
                rootView.getWindowVisibleDisplayFrame(r)
                val visibleHeight: Int = r.height()
                println("" + visibleHeight)
                if (rootViewVisibleHeight == 0) {
                    rootViewVisibleHeight = visibleHeight
                    return
                }

                //根視圖顯示高度沒有變化,可以看作軟鍵盤顯示/隱藏狀態(tài)沒有改變
                if (rootViewVisibleHeight == visibleHeight) {
                    return
                }

                //根視圖顯示高度變小超過200离福,可以看作軟鍵盤顯示了
                if (rootViewVisibleHeight - visibleHeight > 200) {
                    if (onSoftKeyBoardChangeListener != null) {
                        onSoftKeyBoardChangeListener!!.keyBoardShow(rootViewVisibleHeight - visibleHeight)
                    }
                    rootViewVisibleHeight = visibleHeight
                    return
                }

                //根視圖顯示高度變大超過200杖狼,可以看作軟鍵盤隱藏了
                if (visibleHeight - rootViewVisibleHeight > 200) {
                    if (onSoftKeyBoardChangeListener != null) {
                        onSoftKeyBoardChangeListener!!.keyBoardHide(visibleHeight - rootViewVisibleHeight)
                    }
                    rootViewVisibleHeight = visibleHeight
                    return
                }
            }
        })
    }
}

用法:

       //設(shè)置鍵盤的監(jiān)聽
        SoftKeyBoardListener.setListener(activity, object : OnSoftKeyBoardChangeListener {
            override fun keyBoardShow(height: Int) {
                Log.d("鍵盤監(jiān)聽", "彈起")
   
            }

            override fun keyBoardHide(height: Int) {
                Log.d("鍵盤監(jiān)聽", "回收")
    
            }
        })
3.指定輸入框的輸入方式

這個(gè)其實(shí)是edittext的屬性,修改inputType妖爷。
例子:editText.inputType = InputType.TYPE_CLASS_NUMBER
這個(gè)就表示輸入框只想要純數(shù)字蝶涩,其他的輸入類型可以自己研究下。
輸入框的錯(cuò)誤提示:editText.error = "輸入內(nèi)容不可為空"
聚焦和非聚焦ui樣式的改變(通過drawable)
https://blog.csdn.net/tracydragonlxy/article/details/100558915
其他關(guān)于輸入框的知識(shí)點(diǎn)都很簡(jiǎn)單,需要的時(shí)候一搜就可以了。
最后推薦一個(gè)還不錯(cuò)的自定義輸入框:
https://github.com/wrapp-archive/floatlabelededittext

四 . 一個(gè)非常好用的時(shí)間選擇器

https://github.com/JZXiang/TimePickerDialog

五 .圖片保存和分享

1.圖片保存

圖片保存通常就是將bitmap在手機(jī)上保存為jpg,png等格式圖片绿聘。
這里有幾個(gè)注意點(diǎn):
1.文件讀寫權(quán)限
2.判斷手機(jī)是否有外部存儲(chǔ)卡暗挑,若沒有則只能保存在App內(nèi)部存儲(chǔ)
3.圖片保存后并不會(huì)直接在相冊(cè)里顯示,而是要發(fā)出廣播通知系統(tǒng)刷新媒體庫
我的一個(gè)工具類在這里斜友,比較清晰炸裆,可以作為一個(gè)參考,后期再加上接口回調(diào)鲜屏,將保存結(jié)果成功或失敗回調(diào)出去烹看。

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Environment
import android.os.Handler
import android.os.Message
import android.util.Log
import android.widget.Toast
import androidx.browser.customtabs.CustomTabsClient.getPackageName
import androidx.core.content.FileProvider
import com.matrix.framework.utils.DirUtils.getCacheDir
import com.qr.scanlife.R
import com.qr.scanlife.base.App
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import kotlin.concurrent.thread

/**
 * 保存圖片工具類 將bitmap對(duì)象保存到本地相冊(cè)
 *
 **/

class SaveImageUnit {

    //讀寫權(quán)限!
    companion object {
        val instance: SaveImageUnit by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { SaveImageUnit() }
    }

    //保存圖片的文件夾地址
    var appDir: File? = null
    private val TAG = "圖片保存"
    val context = App.context
    var mediaScanIntent: Intent? = null
    val saveSucCode = 2211

    //檢查保存的文件夾是否存在 不存在則創(chuàng)建一個(gè)
    private fun checkDir() {
        val state = Environment.getExternalStorageState()
        if (Environment.MEDIA_MOUNTED == state) {
            //如果有外部?jī)?nèi)存卡可進(jìn)行讀寫 則建在外部?jī)?nèi)存卡上
            appDir = File(
                Environment.getExternalStorageDirectory().absolutePath + File.separator + Environment.DIRECTORY_PICTURES + File.separator + context.getText(
                    R.string.app_name
                )
            )
            if (!appDir!!.exists()) {
                appDir!!.mkdir()
            }
        } else {//否則將文件夾建在 APP內(nèi)部存儲(chǔ)上
            appDir =
                File(context.filesDir.absolutePath + File.separator + context.getText(R.string.app_name))
            if (!appDir!!.exists()) {
                appDir!!.mkdir()
            }
        }
        Log.d(TAG, "圖片文件夾地址${appDir?.absolutePath}")
    }

    //保存bitmap到指定文件夾 并發(fā)出廣播通知系統(tǒng)刷新媒體庫
    fun saveBitmap(bitmap: Bitmap, imageName: String) {
        Toast.makeText(context, App.context.getText(R.string.saving), Toast.LENGTH_SHORT).show()
        checkDir()

        val file = File(appDir, "$imageName.jpg")
        //準(zhǔn)備好發(fā)出廣播 通知系統(tǒng)媒體 刷新相冊(cè) 在相冊(cè)中顯示出圖片
        mediaScanIntent =
            Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file))

        Log.d(TAG, "圖片地址${file.absolutePath}")
        thread {
            try {
                val fileOutputStream = FileOutputStream(file)
                /**
                 * quality:100
                 * 為不壓縮
                 */
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)
                fileOutputStream.flush()
                fileOutputStream.close()
                val msg = Message()
                msg.what = saveSucCode
                msg.obj = file.absolutePath
                handler.sendMessage(msg)
            } catch (e: FileNotFoundException) {
                e.printStackTrace()
                Log.d(TAG, "保存失敗1${e.message}")
                Toast.makeText(context, "${App.context.getText(R.string.save_failed)}:${e.message}", Toast.LENGTH_SHORT).show()
            } catch (e: IOException) {
                e.printStackTrace()
                Log.d(TAG, "保存失敗2${e.message}")
                Toast.makeText(context, "${App.context.getText(R.string.save_failed)}:${e.message}", Toast.LENGTH_SHORT).show()
            }
        }
    }

    @SuppressLint("HandlerLeak")
    private val handler = object : Handler() {
        //接收信息
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            //判斷信息識(shí)別碼 根據(jù)不同的識(shí)別碼進(jìn)行不同動(dòng)作
            when (msg.what) {
                saveSucCode -> {
                    context.sendBroadcast(mediaScanIntent)
                    val path: String? = msg.obj as? String
                    Toast.makeText(context, "${App.context.getText(R.string.save_success)} ${App.context.getText(R.string.image_path)}:$path", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    //保存文件到app緩存目錄準(zhǔn)備分享 耗時(shí)操作 請(qǐng)最好在異步線程調(diào)用
    fun cacheBitmapForShare(bitmap: Bitmap): Uri? {
        val dir = File(getCacheDir().absolutePath + File.separator + "Share")
        if (!dir.exists()) {
            dir.mkdir()
        }
        val file = File(dir,"Share${System.currentTimeMillis()}.jpg" )
        Log.d(TAG, "圖片緩存地址${file.absolutePath}")
        try {
            val fileOutputStream = FileOutputStream(file)
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)
            fileOutputStream.flush()
            fileOutputStream.close()
            val uri=FileProvider.getUriForFile(context,context.packageName+".fileProvider",file)
            return uri
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
            Log.d(TAG, "緩存失敗1${e.message}")
        } catch (e: IOException) {
            e.printStackTrace()
            Log.d(TAG, "緩存失敗2${e.message}")
        }
        return null
    }
}
2.圖片分享

圖片分享之前需要將圖片保存洛史,然后將保存的文件uri作為分享內(nèi)容使用intent分享出去惯殊。
這里有兩個(gè)坑:
首先保存的位置應(yīng)該是App的緩存文件夾(系統(tǒng)隨時(shí)回收),不會(huì)占用過多的空間也殖,產(chǎn)生垃圾文件土思。
其次,如果保存在了緩存文件夾忆嗜,則系統(tǒng)不允許App直接將文件uri暴露出去己儒,而要通過FileProvider
file provider用法:
http://www.reibang.com/p/f0b2cf0e0353
然后關(guān)于分享文件可以看上邊的cacheBitmapForShare方法,具體用法:

    private fun shareImg(bitmap:Bitmap) {
        val uri = SaveImageUnit.instance.cacheBitmapForShare(bitmap)
        Log.d("圖片分享uri", uri.toString())
        val shareIntent = Intent(Intent.ACTION_SEND)
        shareIntent.putExtra(Intent.EXTRA_STREAM, uri)
        shareIntent.type = "image/*" //設(shè)置分享內(nèi)容的類型:圖片
        try {
            startActivity(
                Intent.createChooser(
                    shareIntent,
                    getString("Share")
                )
            )
        } catch (e: Exception) {
            Log.d("圖片分享", e.toString())
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捆毫,一起剝皮案震驚了整個(gè)濱河市闪湾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绩卤,老刑警劉巖途样,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異濒憋,居然都是意外死亡何暇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門凛驮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裆站,“玉大人,你說我怎么就攤上這事辐烂《舨澹” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵纠修,是天一觀的道長(zhǎng)胳嘲。 經(jīng)常有香客問我,道長(zhǎng)扣草,這世上最難降的妖魔是什么了牛? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任颜屠,我火速辦了婚禮,結(jié)果婚禮上鹰祸,老公的妹妹穿的比我還像新娘甫窟。我一直安慰自己,他們只是感情好蛙婴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布粗井。 她就那樣靜靜地躺著,像睡著了一般街图。 火紅的嫁衣襯著肌膚如雪浇衬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天餐济,我揣著相機(jī)與錄音耘擂,去河邊找鬼。 笑死絮姆,一個(gè)胖子當(dāng)著我的面吹牛醉冤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播篙悯,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚁阳,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了辕近?” 一聲冷哼從身側(cè)響起韵吨,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎移宅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椿疗,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漏峰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了届榄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浅乔。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖铝条,靈堂內(nèi)的尸體忽然破棺而出靖苇,到底是詐尸還是另有隱情,我是刑警寧澤班缰,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布贤壁,位于F島的核電站,受9級(jí)特大地震影響埠忘,放射性物質(zhì)發(fā)生泄漏脾拆。R本人自食惡果不足惜馒索,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望名船。 院中可真熱鬧绰上,春花似錦、人聲如沸渠驼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迷扇。三九已至疯趟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谋梭,已是汗流浹背信峻。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瓮床,地道東北人盹舞。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像隘庄,于是被迫代替她去往敵國(guó)和親踢步。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355