1

我正在开发一个 android 应用程序,在填写详细信息后的这一页中,在页面末尾我需要放置一些图像视图或片段,用户可以通过触摸在其中签署他们的签名。这样我就可以在单击提交时将该签名保存为图像。

我已经用谷歌搜索了这个,但我没有得到任何教程类型的东西开始。如果你们知道,请帮助我或分享一些链接。

提前致谢, Srikanth A 这是我的课程文件,

package com.example.test_signature;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable.Callback;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

public class SignatureView extends SurfaceView implements OnTouchListener, Callback, android.view.SurfaceHolder.Callback {

    public SignatureView(Context context) {
            super(context);
            init();
    }

    public SignatureView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
    }

    private void init(){
            this.setBackgroundColor(Color.WHITE);
            mPaint = new Paint();
            mPaint.setColor(Color.BLACK);
            mPaint.setStrokeWidth(3);
            this.setOnTouchListener(this);
            this.getHolder().addCallback(this);
    }

    public void setStrokeWidth(float width){
            mPaint.setStrokeWidth(width);
            this.invalidate();
    }

    public void setColor(int color){
            mPaint.setColor(color);
            this.invalidate();
    }

    public void clear(){
            mDots = new ArrayList<List<Dot>>();
            //To prevent an exception
            mDots.add(new ArrayList<Dot>());
            this.invalidate();
    }

    private List<List<Dot>> mDots = new ArrayList<List<Dot>>();

    private class Dot{

            public float X = 0;
            public float Y = 0;

            public Dot(float x, float y){
                    X = x;
                    Y = y;
            }
    }

    @Override
    public boolean onTouch(View view, MotionEvent event) {
            //mLastActivity = Calendar.getInstance();
            switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
                    mDots.add(new ArrayList<Dot>());
                    mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
                    this.invalidate();
                    break;
            case MotionEvent.ACTION_UP:
                    mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
                    this.invalidate();
                    break;
            case MotionEvent.ACTION_MOVE:
                    mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
                    this.invalidate();
                    break;
            }
            return true;
    }

    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

    }

    public void surfaceCreated(SurfaceHolder arg0) {

    }

    public void surfaceDestroyed(SurfaceHolder arg0) {

    }

    public Paint mPaint;
    @Override
    protected void onDraw(Canvas canvas) {
            for(List<Dot> dots : mDots){
                for(int i = 0; i < dots.size(); i++){
                    if(i - 1 == -1)
                            continue;
                    canvas.drawLine(dots.get(i - 1).X, dots.get(i - 1).Y, dots.get(i).X, dots.get(i).Y, mPaint);
                }
            }
    }

    public Bitmap getBitmap(){
            Bitmap b = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888); 
        Canvas c = new Canvas(b);
        this.draw(c);
        return b;
    }

    public boolean exportFile(String pathString, String fileString){
            File path = new File(pathString);
            path.mkdirs();
            if(!fileString.toLowerCase(Locale.ENGLISH).contains(".png")){
                    fileString += ".png";
            }
            File file = new File(path, fileString);
            FileOutputStream out;
            try {
                    out = new FileOutputStream(file);
            this.getBitmap().compress(Bitmap.CompressFormat.PNG, 90, out);
            return true;
            } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }
            return false;
    }
}

这是我的 XML 文件,我在其中创建了供用户签名的视图。

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".SignatureView" >    

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

    <com.example.test_signature.SignatureView
        android:id="@+id/signature"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:height="18dp"
        android:width="18dp" />

</RelativeLayout>

我创建了这个示例来测试签名功能。但是每当我运行这段代码时,我的应用程序就会崩溃。任何人请帮帮我。我想我在我的 XML 中犯了一个错误。

@FabianCook:请看一下我粘贴的代码。我已经按照您的程序进行了操作。但是你能告诉我代码中的问题吗?

我已按照您的建议编辑了我的 XML 文件,但我的应用程序在打开时仍然崩溃。

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".SignatureView" >    

    <View
        android:id="@+id/id"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.example.test_signature.SignatureView
        android:id="@+id/signature"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />




</RelativeLayout>
4

2 回答 2

5
public class SignatureView extends SurfaceView implements OnTouchListener, Callback {

        public SignatureView(Context context) {
                super(context);
                init();
        }

        public SignatureView(Context context, AttributeSet attrs) {
                super(context, attrs);
                init();
        }

        private void init(){
                this.setBackgroundColor(Color.WHITE);
                mPaint = new Paint();
                mPaint.setColor(Color.BLACK);
                mPaint.setStrokeWidth(3);
                this.setOnTouchListener(this);
                this.getHolder().addCallback(this);
        }

        public void setStrokeWidth(float width){
                mPaint.setStrokeWidth(width);
                this.invalidate();
        }

        public void setColor(int color){
                mPaint.setColor(color);
                this.invalidate();
        }

        public void clear(){
                mDots = new ArrayList<List<Dot>>();
                //To prevent an exception
                mDots.add(new ArrayList<Dot>());
                this.invalidate();
        }

        private List<List<Dot>> mDots = new ArrayList<List<Dot>>();

        private class Dot{

                public float X = 0;
                public float Y = 0;

                public Dot(float x, float y){
                        X = x;
                        Y = y;
                }
        }

        @Override
        public boolean onTouch(View view, MotionEvent event) {
                //mLastActivity = Calendar.getInstance();
                switch(event.getAction()){
                case MotionEvent.ACTION_DOWN:
                        mDots.add(new ArrayList<Dot>());
                        mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
                        this.invalidate();
                        break;
                case MotionEvent.ACTION_UP:
                        mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
                        this.invalidate();
                        break;
                case MotionEvent.ACTION_MOVE:
                        mDots.get(mDots.size() - 1).add(new Dot(event.getX(), event.getY()));
                        this.invalidate();
                        break;
                }
                return true;
        }

        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder arg0) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder arg0) {

        }

        public Paint mPaint;
        @Override
        protected void onDraw(Canvas canvas) {
                for(List<Dot> dots : mDots){
                    for(int i = 0; i < dots.size(); i++){
                        if(i - 1 == -1)
                                continue;
                        canvas.drawLine(dots.get(i - 1).X, dots.get(i - 1).Y, dots.get(i).X, dots.get(i).Y, mPaint);
                    }
                }
        }

        public Bitmap getBitmap(){
                Bitmap b = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888); 
            Canvas c = new Canvas(b);
            this.draw(c);
            return b;
        }

        public boolean exportFile(String pathString, String fileString){
                File path = new File(pathString);
                path.mkdirs();
                if(!fileString.toLowerCase(Locale.ENGLISH).contains(".png")){
                        fileString += ".png";
                }
                File file = new File(path, fileString);
                FileOutputStream out;
                try {
                        out = new FileOutputStream(file);
                this.getBitmap().compress(Bitmap.CompressFormat.PNG, 90, out);
                return true;
                } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                return false;
        }
}

我认为代码解释了它的自我

这段代码负责一切。有一些不错的小功能,用于不同的事情,比如将图像保存到文件等。

将它放在您的一个包中,然后在您的 XML 文件中替换

<View android:id="@+id/id"/>

<package.name.SignatureView android:id="@+id/id"/>

用法

在您的包中创建一个名为 的新类SignatureView,删除此文件中除第一行之外的所有内容,您应该留下package your.package.name

在第三行粘贴上面的代码并按下Ctrl-Shift-O它,它将导入您需要的所有内容。

保存此文件,然后构建您的项目。

在您的 XML 文件中使用:

<your.package.name.SignatureView 
    android:id="@+id/signature" 
    android:width="match_parent"
    android:height="match_parent"/>

保存并构建您的项目。

在您的活动中,您可以使用:

SignatureView mSignature;

mSignature = (SignatureView) this.findViewById(R.id.signature);

然后访问将签名保存到文件所需的功能:

mSignature.exportFile("/mnt/sdcard/", "signaturefile.png");
于 2013-10-29T09:25:43.370 回答
1

希望这段代码可以帮助你:)

esign_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


    <android.gesture.GestureOverlayView
        android:id="@+id/signaturePad"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="5"
        android:background="@android:color/white"
        android:clickable="false"
        android:eventsInterceptionEnabled="true"
        android:fadeEnabled="false"
        android:gestureColor="#0000ff"
        android:gestureStrokeLengthThreshold="0.1"
        android:gestureStrokeType="multiple"
        android:longClickable="false"
        android:orientation="vertical"
        android:uncertainGestureColor="#000000"
        android:splitMotionEvents="true" 
        android:fadeOffset="10000000">

    </android.gesture.GestureOverlayView>

    <RelativeLayout
        android:id="@+id/rellay_esign_donebutton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="10dp"
         >
 <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        >
        <Button
            android:id="@+id/DoneButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Done" />

         <Button
             android:id="@+id/ClearButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Clear" />
</LinearLayout>
    </RelativeLayout>

</LinearLayout>

签名.java

public class Esignature extends Activity {
    GestureOverlayView gestureView;
    String path;
    File file;
    Bitmap bitmap;
    public boolean gestureTouch=false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.esign_main);



        Button donebutton = (Button) findViewById(R.id.DoneButton);
        donebutton.setText("Done");
        Button clearButton = (Button) findViewById(R.id.ClearButton);
        clearButton.setText("Clear");

        path=Environment.getExternalStorageDirectory()+"/signature.png";
        file = new File(path);
        file.delete();
        gestureView = (GestureOverlayView) findViewById(R.id.signaturePad);
        gestureView.setDrawingCacheEnabled(true);

        gestureView.setAlwaysDrawnWithCacheEnabled(true);
        gestureView.setHapticFeedbackEnabled(false);
        gestureView.cancelLongPress();
        gestureView.cancelClearAnimation();
        gestureView.addOnGestureListener(new OnGestureListener() {

            @Override
            public void onGesture(GestureOverlayView arg0, MotionEvent arg1) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onGestureCancelled(GestureOverlayView arg0,
                    MotionEvent arg1) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onGestureEnded(GestureOverlayView arg0, MotionEvent arg1) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onGestureStarted(GestureOverlayView arg0,
                    MotionEvent arg1) {
                // TODO Auto-generated method stub
                if (arg1.getAction()==MotionEvent.ACTION_MOVE){
                    gestureTouch=false;                     
             }
             else 
             {
                    gestureTouch=true;
            }
            }});

        donebutton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                try {
                    bitmap = Bitmap.createBitmap(gestureView.getDrawingCache());
                    file.createNewFile();
                    FileOutputStream fos = new FileOutputStream(file);
                    fos = new FileOutputStream(file);
                    // compress to specified format (PNG), quality - which is
                    // ignored for PNG, and out stream
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            if(gestureTouch==false)
            {
                setResult(0);
                finish();
            }
            else
            {
                setResult(1);
                finish();
            }
            }
        });

        clearButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                gestureView.invalidate();
                gestureView.clear(true);
                gestureView.clearAnimation();
                gestureView.cancelClearAnimation();
            }
        });
    }

}

于 2014-01-31T09:32:01.660 回答