欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发-View生成图片海报的实现方式

程序员文章站 2022-07-05 09:35:33
前 言前段时间apk安装包下载体验地址:可以扫描以下二维码进行下载安装,或者点击以下链接 http://app.fukaimei.top/3dTagView 进行下载安装体验。———————— The end ————————码字不易,如果您觉得这篇博客写的比较好的话,可以赞赏一杯咖啡吧~~......

前 言

一般在一个应用内都是有分享的功能,分享一般有两个方式:一种是文字分享,另一种是图片分享。图片分享一般都是直接在应用内生成View视图的截图保存到手机的SD卡或者上传到服务器。那么下面就来看如何实现View生成图片海报的功能吧!

编码实现

创建一个 xml 布局 activity_main.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="match_parent"
    android:gravity="center"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layout_poster"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@android:color/white"
        android:orientation="vertical">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:scaleType="fitXY"
            android:src="@drawable/bg_cover" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:layout_margin="5dp"
                android:orientation="vertical">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dp"
                    android:text="ID:fukaimei"
                    android:textColor="@android:color/black"
                    android:textSize="14sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dp"
                    android:text="昵称:_彼岸雨敲窗_"
                    android:textColor="@android:color/black"
                    android:textSize="14sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dp"
                    android:text="个性签名:愿你出走半生,归来仍是少年。"
                    android:textColor="@android:color/black"
                    android:textSize="14sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="5dp"
                    android:layout_marginBottom="5dp"
                    android:text="博客地址:https://blog.csdn.net/fukaimei"
                    android:textColor="@android:color/black"
                    android:textSize="14sp" />

            </LinearLayout>

            <ImageView
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:layout_alignParentEnd="true"
                android:layout_marginStart="5dp"
                android:layout_marginTop="15dp"
                android:layout_marginEnd="5dp"
                android:layout_marginBottom="5dp"
                android:scaleType="fitXY"
                android:src="@drawable/qr_user" />

        </RelativeLayout>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout_save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"
        android:gravity="center"
        android:orientation="vertical">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/img_download" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:text="生成海报并保存到SD卡" />

    </LinearLayout>

</RelativeLayout>

该布局的作用是用于生成图片海报时的界面预览。

创建一个用于View生成图片海报文件 MainActivity.java,逻辑代码如下:

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_STATE_CODE = 1010;

    private LinearLayout layout_poster;
    private LinearLayout layout_save;

    private Bitmap mBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        layout_poster = (LinearLayout) findViewById(R.id.layout_poster);
        layout_save = (LinearLayout) findViewById(R.id.layout_save);
        layout_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 保存海报图片
                savePoster();
            }
        });
    }

    /**
     * 保存海报图片
     */
    private void savePoster() {

        // 1.View截图
        layout_poster.setDrawingCacheEnabled(true);
        // 重新测量View
        layout_poster.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        // 2.创建一个Bitmap
        mBitmap = layout_poster.getDrawingCache();
        // 3.保存到SD卡
        if (mBitmap != null) {
            //判断是否为Android 6.0 以上的系统版本,如果是,需要动态添加权限
            if (Build.VERSION.SDK_INT >= 23) {
                requestPermissions();
            } else {
                saveToLocal(mBitmap);
            }
        }

    }

    private void requestPermissions() {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            // 申请一个(或多个)权限,并提供用于回调返回的获取码(用户定义)
            ActivityCompat.requestPermissions(this, new String[]{
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            }, REQUEST_STATE_CODE);
        } else {
            saveToLocal(mBitmap);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_STATE_CODE:
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    saveToLocal(mBitmap);
                } else {
                    Toast.makeText(this, "权限授予失败,请重新授予", Toast.LENGTH_LONG).show();
                    return;
                }
                break;
            default:
                break;
        }
    }

    /**
     * 保存一张Bitmap图到本地
     */
    private void saveToLocal(Bitmap bitmap) {
        try {
            File appDir = new File(Environment.getExternalStorageDirectory(), "Poster");
            // 没有目录创建目录
            if (!appDir.exists()) {
                appDir.mkdir();
            }
            File file = new File(appDir, "view_" + System.currentTimeMillis() + ".jpg");
            FileOutputStream out;
            try {
                out = new FileOutputStream(file);
                if (bitmap.compress(Bitmap.CompressFormat.PNG, 90, out)) {
                    out.flush();
                    out.close();
                    // 通知图库更新
                    Uri uri = Uri.fromFile(file);
                    Intent scannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri);
                    sendBroadcast(scannerIntent);
                    Toast.makeText(this, "保存图片到相册成功", Toast.LENGTH_SHORT).show();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

该逻辑代码首先重新测量View,然后创建一个Bitmap生成View的截图,最后把生成的截图保存到SD卡里。

因为用到截图保存到SD卡的功能,所以需要在AndroidManifest.xml添加 SD卡读取权限。

    <!-- SD卡读取权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

如何创建的项目目标编译的版本是29(Android 10)以上的话,还需要在AndroidManifest.xml的application节点添加上android:requestLegacyExternalStorage=“true”。如下:

<application
        ...
        android:requestLegacyExternalStorage="true">
        ...
</application>

apk安装包下载体验地址:

可以扫描以下二维码进行下载安装,或者点击以下链接 http://app.fukaimei.top/2vpm 进行下载安装体验。
Android开发-View生成图片海报的实现方式

———————— The end ————————

码字不易,如果您觉得这篇博客写的比较好的话,可以赞赏一杯咖啡吧~~
Android开发-View生成图片海报的实现方式


本文地址:https://blog.csdn.net/fukaimei/article/details/109327090