Tuesday 3 November 2015

Android Programming - Zoom Image View

Assalamu'alaikum.

Hari ni aku try satu contoh untuk buat app yg ada fungsi "ZOOM gambar"

Rujukan akau adalah dari link berikut:

http://www.c-sharpcorner.com/UploadFile/88b6e5/multi-touch-panning-pinch-zoom-image-view-in-android-using/.

Aku copy sebiji macam yg dia buat :). Alhamdulillah senang sangat :). Semoga Mr. Chintan Rathod dipermudahkan urusannya & mendapat hidayah asbab perkongsian ilmu ni.

Berikut adalah coding yg aku copy & paste dlm android project aku. Jgan tanya aku apa maksud setiap line dlm coding tu... aku copy & paste je :)


Create hello world android project. Lepas tu create  Java class. 

TouchImageView

package com.hobby.azbiha.besarkanimage;

import android.widget.ImageView;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
//import android.widget.ImageView;/** * Created by Samsung on 11/3/2015. */public class TouchImageView extends ImageView {
    Matrix matrix;
    // We can be in one of these 3 states    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;

    int mode = NONE;

    // Remember some things for zooming    PointF last = new PointF();
    PointF start = new PointF();
    float minScale = 1f;
    float maxScale = 3f;
    float[] m;
    int viewWidth, viewHeight;

    static final int CLICK = 3;

    float saveScale = 1f;

    protected float origWidth, origHeight;

    int oldMeasuredWidth, oldMeasuredHeight;

    ScaleGestureDetector mScaleDetector;

    Context context;

    public TouchImageView(Context context) {
        super(context);
        sharedConstructing(context);
    }

    public TouchImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        sharedConstructing(context);
    }

    private void sharedConstructing(Context context) {

        super.setClickable(true);

        this.context = context;

        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());

        matrix = new Matrix();

        m = new float[9];

        setImageMatrix(matrix);

        setScaleType(ScaleType.MATRIX);

        setOnTouchListener(new OnTouchListener() {

            @Override            public boolean onTouch(View v, MotionEvent event) {

                mScaleDetector.onTouchEvent(event);

                PointF curr = new PointF(event.getX(), event.getY());

                switch (event.getAction()) {

                    case MotionEvent.ACTION_DOWN:

                        last.set(curr);

                        start.set(last);

                        mode = DRAG;

                        break;

                    case MotionEvent.ACTION_MOVE:

                        if (mode == DRAG) {

                            float deltaX = curr.x - last.x;

                            float deltaY = curr.y - last.y;

                            float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);

                            float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);

                            matrix.postTranslate(fixTransX, fixTransY);

                            fixTrans();

                            last.set(curr.x, curr.y);

                        }

                        break;

                    case MotionEvent.ACTION_UP:

                        mode = NONE;

                        int xDiff = (int) Math.abs(curr.x - start.x);

                        int yDiff = (int) Math.abs(curr.y - start.y);

                        if (xDiff < CLICK && yDiff < CLICK)

                            performClick();

                        break;

                    case MotionEvent.ACTION_POINTER_UP:

                        mode = NONE;

                        break;

                }

                setImageMatrix(matrix);

                invalidate();

                return true; // indicate event was handled
            }

        });
    }

    public void setMaxZoom(float x) {

        maxScale = x;

    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        @Override        public boolean onScaleBegin(ScaleGestureDetector detector) {

            mode = ZOOM;

            return true;

        }

        @Override        public boolean onScale(ScaleGestureDetector detector) {

            float mScaleFactor = detector.getScaleFactor();

            float origScale = saveScale;

            saveScale *= mScaleFactor;

            if (saveScale > maxScale) {

                saveScale = maxScale;

                mScaleFactor = maxScale / origScale;

            } else if (saveScale < minScale) {

                saveScale = minScale;

                mScaleFactor = minScale / origScale;

            }

            if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)

                matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2);

            else
                matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());

            fixTrans();

            return true;

        }

    }

    void fixTrans() {

        matrix.getValues(m);

        float transX = m[Matrix.MTRANS_X];

        float transY = m[Matrix.MTRANS_Y];

        float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);

        float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale);

        if (fixTransX != 0 || fixTransY != 0)

            matrix.postTranslate(fixTransX, fixTransY);

    }



    float getFixTrans(float trans, float viewSize, float contentSize) {

        float minTrans, maxTrans;

        if (contentSize <= viewSize) {

            minTrans = 0;

            maxTrans = viewSize - contentSize;

        } else {

            minTrans = viewSize - contentSize;

            maxTrans = 0;

        }

        if (trans < minTrans)

            return -trans + minTrans;

        if (trans > maxTrans)

            return -trans + maxTrans;

        return 0;

    }

    float getFixDragTrans(float delta, float viewSize, float contentSize) {

        if (contentSize <= viewSize) {

            return 0;

        }

        return delta;

    }

    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        viewWidth = MeasureSpec.getSize(widthMeasureSpec);

        viewHeight = MeasureSpec.getSize(heightMeasureSpec);

        //        // Rescales image on rotation        //        if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
                || viewWidth == 0 || viewHeight == 0)

            return;

        oldMeasuredHeight = viewHeight;

        oldMeasuredWidth = viewWidth;

        if (saveScale == 1) {

            //Fit to screen.
            float scale;

            Drawable drawable = getDrawable();

            if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)

                return;

            int bmWidth = drawable.getIntrinsicWidth();

            int bmHeight = drawable.getIntrinsicHeight();

            Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);

            float scaleX = (float) viewWidth / (float) bmWidth;

            float scaleY = (float) viewHeight / (float) bmHeight;

            scale = Math.min(scaleX, scaleY);

            matrix.setScale(scale, scale);

            // Center the image
            float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);

            float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);

            redundantYSpace /= (float) 2;

            redundantXSpace /= (float) 2;

            matrix.postTranslate(redundantXSpace, redundantYSpace);

            origWidth = viewWidth - 2 * redundantXSpace;

            origHeight = viewHeight - 2 * redundantYSpace;

            setImageMatrix(matrix);

        }

        fixTrans();

    }
}



Aku copy image file dalam "drawable" folder.






Last sekali beberapa line java coding dalam MainActivity.java.



MainActivity.java


package com.hobby.azbiha.besarkanimage;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);        TouchImageView img = new TouchImageView(this);
        img.setImageResource(R.drawable.faiz);
        img.setMaxZoom(4f);
        setContentView(img);
    }
}





Hasilnya Seperti Berikut:







Thursday 20 November 2014

Android programming - Phone Number Utility

Click button utk buat call.

Ini adalah salah satu fungsi dalam app Kad Jemputan aku. Tapi source code Kad Jemputan aku dah hilang :(. Jadi aku kena cari semula semua fungsi2 yang aku guna untuk Kad Jemputan.

Salah satu fungsi yang aku guna adalah Phone Utility.

Dari android studio, aku create New Project. Aku guna default source code yang Android Studio generate iaitu "Hello World". Menggunakan source code yang sama, aku tambah beberapa command line untuk Phone Utility. Semua command yg aku tambah di highlighted dengan warna kuning.

Moga2 ini akan menjadi rujukan aku masa depan & sapa-sapa yang memerlukan. Somoga ada manfaat.



Ada 3 file ni.

MainActivity.java

package com.hobby.azbiha.myapplication;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    Button b_Mariam, b_Maslina;
    public static final String MARIAM = "012xxxxxxx";
    public static final String MASLINA = "01xxxxxxx";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Button b_Mariam = (Button) findViewById(R.id.btnMariam);
        Button b_Maslina = (Button) findViewById(R.id.btnMaslina);
    
        b_Mariam.setOnClickListener(this);
        b_Maslina.setOnClickListener(this);
    
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View arg1) {
        switch (arg1.getId()) {
            case R.id.btnMariam:
                Intent b1 = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + MainActivity.MARIAM));
                startActivity(b1);
                break;

            case R.id.btnMaslina:

                Intent b2 = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + MainActivity.MASLINA));
                startActivity(b2);
                break;

        }

    }
}


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.hobby.azbiha.myapplication" >

    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme" >
        <uses-permission android:name="android.permission.CALL_PHONE" />
        <uses-permission android:name="android.permission.modify_phone_state" />

        <uses-permission android:name="android.permission.READ_PHONE_STATE" />

        <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
        <activity            android:name=".MainActivity"            android:label="@string/app_name"            android:theme="@style/AppTheme.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>





activity_main.xml

<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"    android:layout_height="match_parent" android:fitsSystemWindows="true"    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout android:layout_height="wrap_content"        android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar android:id="@+id/toolbar"            android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"            android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton android:id="@+id/fab"        android:layout_width="wrap_content" android:layout_height="wrap_content"        android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin"        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

content_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"    xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin"    app:layout_behavior="@string/appbar_scrolling_view_behavior"    tools:showIn="@layout/activity_main" tools:context=".MainActivity">

    <TextView android:text="Hello World!" android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/textView" />

    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Maslina"        android:id="@+id/btnMaslina"        android:layout_below="@+id/textView"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_marginTop="34dp" />

    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Mariam"        android:id="@+id/btnMariam"        android:layout_alignTop="@+id/textView"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true" />
</RelativeLayout>

OUTPUT





Monday 22 April 2013

Assalamu'alaikum,

Hmm... hari ni nak update sikit berkaitan excel macro...

Isteri baru start online business... jual sejadah putih, hand made... 

https://www.facebook.com/SejadahPutihByMissmassCollection

Dia minta aku buat simple RESIT template... berkali2 gak dia minta bantuan... tak jalan gakk... last2 dia buat sendiri... heh heh... lps tu baru la aku terhegeh-hegeh nak tolong ... heh heh...

Bila aku "campur tangan"... sooo... start laaa terpikir... takkan nak buat benda niii manually ... hmmm... Mesti nak juga simpan data pelanggan ... toing toing toingg... idea maiii....

Maka terpikir lah aku untuk buat macro (excel macro untuk dia)... InshaAllah dengan macro tu mungkin boleh menyenangkan sedikit kerja di dari segi penyimpanan data pelanggan... Sepatutnya benda2 macam ni lebih baik pakai Ms Access... tp aku tak mahir pakai Access...

So apa yang aku buat adalah...

1- Worksheet untuk masukkan data pelanggan dan senarai sejadah yang dibelinya.


2- Data pelanggan dari worksehhet di atas akan dimasukkan kedalam worksheet SenaraiPenuh":


Worksheet ini merupakan rekod pembelian dari pelanggan.

3- Dalam masa yang sama, data pelanggan dari worksheet pertama tadi juga dimasukkan kedalam worksheet "RESIT". Worksheet ini akan diprint dan diselitkan bersama sejadah yang dibeli oleh pelanggan.



Walaubagaimanapun, aku masih ada sedikit masalah lagi. Aku nak protect worksheet SenaraiPenuh tapi masih boleh diedit oleh macro...

Idea aku macam ni:
- Run macro
- Macro ambil semua parameter dari worksheet pertama.
- Macro unprotect worksheet SenaraiPenuh dan isi data pelanggan
- Macro protect semua worksheet.

Masalahnya macam bila protect/unprotect, excel akan request password utk unprotect/protect worksheet.
So Macam mana nak bagi macro boleh keyin password yang direquest oleh excel. Hmmmmm...

Itu saja buat masa ni...

Wassalam

Friday 25 January 2013

Faraid Calculator Lite (Version 7) is published.


Improvement:
- The improvement only for Bahasa Malaysia.
- Allow more numbers of heirs.
- Has a fix amount of nilai harta pusaka in RM25000.
- Add function to show individual portion.
- An email option is disabled from "Bhg Individu".

Feel free to use it & please give your feedback for any problem or miscalculation. Any suggestion for an improvement are highly appreciated.

If you think that this is useful, please remember me in your "dua".

Thanks,

Brs,
AZH.

Saturday 19 January 2013

Assalamu'alaikum,

Hmm dah lama x update status Faraid Calculator Lite....

Alhamdulillah serta tiada daya dan upaya melainkan dengan izinNya. Minggu ni aku dapat mengemaskinikan calculator tu. Untuk version yang terbaru ni aku telah tambah fungsi untuk paparkan bahagian setiap waris.
Selain dari itu, dari paparan pada bahagian setiap waris itu juga, mempunya "button" email. Dengan menekan button ini, app tersebut akan membuka email app di dalam android handphone/tablet serta mengisi info seperti yang tertera di dalam paparan bahagian individu. Had bilangan waris benarkan melebihi dari satu untuk lain-lain waris selain anak dan had bilangan anak (L) & anak (P) juga dibenarkan melebihi 2.

Buat masa ini, version terbaru masih belum di upload ke "Google Play". Aku masih berfikir-fikir samada perlu atau tidak untuk aku menjualnya atau masih mengekalkan applikasi ini secara percuma. Harganya tidaklah semahal mana. Harga tersebut merupakan "kos" masa yang aku luangkan untuk menghasilkan app ini serta beberapa manipulasi & formula yang aku perlu buat untuk menghasilkan bahagian waris faraid di dalam bentuk pecahan.

Memandangkan kebanyakan pengguna applikasi ini (dari statistik) adalah dari Indonesia, Malaysia dan Singapura, maka, aku tumpukan applikasi ini hanya di dalam Bahasa Malaysia. Aku yakin Bahasa Malaysia boleh juga difahami oleh pengguna di Indonesia & Singapura. Sekiranya ada permintaan untuk menukarkannya ke bahasa yang lain, maka barulah aku akan menghasilkannya untuk pengguna yang berbahasa tersebut.

Di bawah ni aku "tampalkan" "snapshot" untuk Faraid Calculator versi terbaru:





Paparan utama untuk Faraid Calculator Versi baru (hampir sama dengan V6).
- Tambahan:
   - Button "Bhg Individu" : Untuk memaparkan bahagian setiap waris faraid.
   - Bahagian "Nilai harta pusaka (RM)". Nilai yang dimasukkan akan diambil kira dan akan dipaparkan di dalam bahagian "Nilai (RM) untuk setiap waris yang berkaitan.



Paparan Srtiap Individu merupakan paparan bahagian yang akan diperolehi oleh setiap waris.
Bahagian yang dipaprkan boleh di-email dengan menekan "button" E-mail.



Setakat ini dulu buat masa ni.

Wassalam.

~ AZH ~



Friday 23 November 2012

Sedikit update.

Hari ni aku buat random checking untuk Faraid Calculator aku.

Dari hasil ujian... kelihatannya semua kombinasi waris seolah2 berfungsi dengan betul & belum jumpa sebarang problem lagi. Walaubagaimana pun ujian akan diteruskan.

Hari ni juga aku menambah baik layout untuk faraid calculator tuu...

Alhamdulillah aku jumpa satu link untuk android coding yang berkaitan dengan apa yang aku cari (draw line utk table layout)...

linknya adalah seperti dibawah:

http://blog.intelligenia.com/2012/02/programacion-movil-en-android.html#more

http://stackoverflow.com/questions/2108456/how-can-i-create-a-table-with-borders-in-android.


Sunday 4 November 2012

Assalamu3alaikum Ustaz2 dan pakar2 pembahagian faraid,

Jika menggunakan android gadjet... nak minta bantuan untuk test app niii (kalkulator untuk pembahagian faraid)...

Tapi dlm versi ni... cuma boleh kira pembahagian dari suami/isteri, anak, ibu dan bapa sahaja. Yang lain2 tu inshaAllah akan ditambah dari masa ke semasa. Tapi sebelum tu... nak kena tambah2 ilmu lagi pasal pembahagian faraid nii... agar dengan itu applikasi ini dapat memberi menfaat kepada yang memrlukan. InshaAllah.

Link applikasi:

https://play.google.com/store/apps/details?id=com.padibenih.fcv2&feature=search_result#?t=W251bGwsMSwyLDEsImNvbS5wYWRpYmVuaWguZmN2MiJd

Diharap dapat memberi komen untuk menambah baik applikasi ini.

JazakAllah.

AZH.