Showing posts with label AndroidAnnotations. Show all posts
Showing posts with label AndroidAnnotations. Show all posts

Friday, December 20, 2013

Generics vs. AndroidAnnotations Android

Hi there!

In the last post i've shown the advantages of AndroidAnnotations against the tratidional instantiation way from Androd using castings while using the method findById(). AndroidAnnotatations are fine, but if for some reason (additional depencency, License or somethign else) you can't use it, there is an alternative to it. Generics solves this problem in my opinion also very elegant.

Pre-Conditions

Do the steps of post AndroidAnnotations and come back to this post when you are done.

BaseActivity with generics

Create the following class in your sample project (Attention: for some reason i don't know, while inserting code snippets here, generic types are not displayed correctly. For this reason i copied the generics like a String "T extends View". Please remove the Strings from it after copying):

import android.app.Activity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;

@SuppressWarnings("unchecked")
public class BaseActivity extends Activity {

    /**
     * Convenience method. Does exactly the same as {@link BaseActivity#initById(Class, int)}
     * @param safetyCheck the class type to be returned
     * @param id the defined R.id... in the layout xml file
     * @return a reference of the specified class type.
     */
    public <"T extends View"> T getReferenceById(Class safetyCheck, final int id) {
        return initById(safetyCheck, id);
    }

    /**
     * Initializes views over id's.
     * @param safetyCheck the class type to be returned
     * @param id the defined R.id... in the layout xml file
     * @return a reference of the specified class type.
     */
    public <"T extends View"> T initById(Class safetyCheck, final int id) {
        return (T) findViewById(id);
    }

    /**
     * Initializes views over id's with onClickListeners.
     * @param id the defined R.id... in the layout xml file
     * @param callback a concrete implementation of {@link OnClickCallback}
     * @return a reference of the specified class type in {@link OnClickCallback}.
     */
    public <"T extends View"> T initWithListener(final int id, final OnClickCallback callback) {
        T type = (T) findViewById(id);
        type.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                callback.onClickPerformed((T) view);
            }
        });
        return type;
    }

    /**
     * Initializes views over id's with onTouchListeners.
     * @param id the defined R.id... in the layout xml file
     * @param callback a concrete implementation of {@link OnTouchCallback}
     * @return a reference of the specified class type in {@link OnTouchCallback}.
     */
    public <"T extends View"> T initWithListener(final int id, final OnTouchCallback callback) {
        T type = (T) findViewById(id);
        type.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                return callback.onTouchPerfomed((T) view, event);
            }

        });
        return type;
    }

    /**
     * Initializes views over id's with onLongClickListeners.
     * @param id the defined R.id... in the layout xml file
     * @param callback a concrete implementation of {@link OnLongClickCallback}
     * @return a reference of the specified class type in {@link OnLongClickCallback}.
     */
    public <"T extends View"> T initWithListener(final int id, final OnLongClickCallback callback) {
        T type = (T) findViewById(id);
        type.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                return callback.onLongClickPerformed((T) view);
            }
        });
        return type;
    }

    /**
     * Implement this interface and add an instance of it to the method
     * {@link BaseActivity#initWithListener(int, Callback)} while initializing your components
     * (Views)
     * @author Ricardo Ferreira
     * @since 20/12/2013
     * @version 1.0
     */
    public interface OnClickCallback<"T extends View"> {
        void onClickPerformed(T view);
    }
    /**
     * Implement this interface and add an instance of it to the method
     * {@link BaseActivity#initWithListener(int, Callback)} while initializing your components
     * (Views)
     * @author Ricardo Ferreira
     * @since 20/12/2013
     * @version 1.0
     */
    public interface OnLongClickCallback<"T extends View"> {
        boolean onLongClickPerformed(T view);
    }
    /**
     * Implement this interface and add an instance of it to the method
     * {@link BaseActivity#initWithListener(int, Callback)} while initializing your components
     * (Views)
     * @author Ricardo Ferreira
     * @since 20/12/2013
     * @version 1.0
     */
    public interface OnTouchCallback<"T extends View"> {
        boolean onTouchPerfomed(T view, MotionEvent event);
    }

}


Modify your MainActivity

Copy paste the next code segment into your MainActiviy. (Attention: for some reason i don't know, while inserting code snippets here, generic types are not displayed correctly. For this reason i copied the generics like a String "T extends View". Please remove the Strings from it after copying):

import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends BaseActivity {

    private OnClickCallback<"Button"> btnClickCallback = new ButtonClickCallback();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initById(TextView.class, R.id.textView1);
        initWithListener(R.id.button1, btnClickCallback);
        initWithListener(R.id.button2, btnClickCallback);
        initWithListener(R.id.button3, btnClickCallback);
        initWithListener(R.id.button4, btnClickCallback);
        initWithListener(R.id.button5, btnClickCallback);
        initWithListener(R.id.button6, btnClickCallback);
        initWithListener(R.id.button7, btnClickCallback);
        initWithListener(R.id.button8, btnClickCallback);
        initWithListener(R.id.button9, btnClickCallback);
        initWithListener(R.id.button10, btnClickCallback);
        initWithListener(R.id.button11, btnClickCallback);
        initWithListener(R.id.button12, btnClickCallback);
        initWithListener(R.id.button13, btnClickCallback);
        initWithListener(R.id.button14, btnClickCallback);
        initWithListener(R.id.button15, btnClickCallback);

    }

    private class ButtonClickCallback implements OnClickCallback<"Button"> {
        @Override
        public void onClickPerformed(Button type) {
            switch (type.getId()) {
            case R.id.button1:
                // returns a Button... do something useful with... if you need to...
                getReferenceById(Button.class, R.id.button1); 
                handleClick();
                break;
            case R.id.textView1:
                // returns a TextView... do something useful with... if you need to...
                getReferenceById(TextView.class, R.id.textView1); 
                handleClick();
                break;
            default:
                handleClick();
                break;
            }
        }
    }

    private void handleClick() {
        Toast.makeText(this, "Generics are even cooler!", Toast.LENGTH_SHORT).show();
    }

}


That's all. Hope you like it.

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Wednesday, December 18, 2013

Write less code with AndroidAnnotations and increase maintainability and readability

Hi there!

Today i'm gonna show how to write less code but simultaneously improve maintainability and readability of your android code. I was so impressed that I wanted to try myself, how good and how easy it really is. In this tuturial i will only show the benefits of AndroidAnnotations and not how to install it. But don't worry. If you decide to use it (and i'm sure you'll will :) there is no magic on how to install it. In this site you'll get all the information you need: AndroidAnnotations

The sample project

We will endup with something like this bellow to show to you the power and simplicity of AndroidAnnotatios. 




MainActivity

Create a simple project and dont change the default names while creating the project. In the folder res>layout>activity_main.xml copy/paste the following code snippet inside of it.




    

    


Initializing the components 

If you initialize the components in the tradional android way, you would end up with a class like this:

package com.treslines.androidannotations;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

    private TextView title;
    private Button button1;
    private Button button2;
    private Button button3;
    private Button button4;
    private Button button5;
    private Button button6;
    private Button button7;
    private Button button8;
    private Button button9;
    private Button button10;
    private Button button11;
    private Button button12;
    private Button button13;
    private Button button14;
    private Button button15;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        title = (TextView) findViewById(R.id.textView1);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);
        button3 = (Button) findViewById(R.id.button3);
        button4 = (Button) findViewById(R.id.button4);
        button5 = (Button) findViewById(R.id.button5);
        button6 = (Button) findViewById(R.id.button6);
        button7 = (Button) findViewById(R.id.button7);
        button8 = (Button) findViewById(R.id.button8);
        button9 = (Button) findViewById(R.id.button9);
        button10 = (Button) findViewById(R.id.button10);
        button11 = (Button) findViewById(R.id.button11);
        button12 = (Button) findViewById(R.id.button12);
        button13 = (Button) findViewById(R.id.button13);
        button14 = (Button) findViewById(R.id.button14);
        button15 = (Button) findViewById(R.id.button15);
        
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);
        button5.setOnClickListener(this);
        button6.setOnClickListener(this);
        button7.setOnClickListener(this);
        button8.setOnClickListener(this);
        button9.setOnClickListener(this);
        button10.setOnClickListener(this);
        button11.setOnClickListener(this);
        button12.setOnClickListener(this);
        button13.setOnClickListener(this);
        button14.setOnClickListener(this);
        button15.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        final int id = view.getId();
        switch (id) {

        case R.id.button1:
            handleClick();
            break;
        case R.id.button2:
            handleClick();
            break;
        case R.id.button3:
            handleClick();
            break;
        case R.id.button4:
            handleClick();
            break;
        case R.id.button5:
            handleClick();
            break;
        case R.id.button6:
            handleClick();
            break;
        case R.id.button7:
            handleClick();
            break;
        case R.id.button8:
            handleClick();
            break;
        case R.id.button9:
            handleClick();
            break;
        case R.id.button10:
            handleClick();
            break;
        case R.id.button11:
            handleClick();
            break;
        case R.id.button12:
            handleClick();
            break;
        case R.id.button13:
            handleClick();
            break;
        case R.id.button14:
            handleClick();
            break;
        case R.id.button15:
            handleClick();
            break;

        default:
            break;
        }

    }
    
    private void handleClick(){
        Toast.makeText(this, "AndroidAnnotations are cool!", Toast.LENGTH_SHORT).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.main, menu);
        return true;
    }
}



The benefits of AndroidAnnotations

If you do the same thing with AndroidAnnotations we endup with something soooooo coooool like this ;)


package com.treslines.withandroidannotations;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.googlecode.androidannotations.annotations.Click;
import com.googlecode.androidannotations.annotations.EActivity;
import com.googlecode.androidannotations.annotations.ViewById;

@EActivity(R.layout.activity_main)
public class MainActivity extends Activity {

    @ViewById(R.id.textView1) protected TextView title;
    @ViewById(R.id.button1) protected Button button1;
    @ViewById(R.id.button2) protected Button button2;
    @ViewById(R.id.button3) protected Button button3;
    @ViewById(R.id.button4) protected Button button4;
    @ViewById(R.id.button5) protected Button button5;
    @ViewById(R.id.button6) protected Button button6;
    @ViewById(R.id.button7) protected Button button7;
    @ViewById(R.id.button8) protected Button button8;
    @ViewById(R.id.button9) protected Button button9;
    @ViewById(R.id.button10) protected Button button10;
    @ViewById(R.id.button11) protected Button button11;
    @ViewById(R.id.button12) protected Button button12;
    @ViewById(R.id.button13) protected Button button13;
    @ViewById(R.id.button14) protected Button button14;
    @ViewById(R.id.button15) protected Button button15;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // NO NEED TO INITIALIZE COMPONENTS ANYMORE
        // ONLY 62 LINES AGAINST 139 LINES (2 TIMES LESS CODE)
        // LESS COPY/PASTE ERROR
    }

    // No switch-cases anymore...
    // Handle clicks together or independently ...
    // No need to implement onClickListener anymore... 
    @Click({R.id.button1,R.id.button2,R.id.button3}) void onButton1Clicked() {handleClick();};
    @Click({R.id.button4,R.id.button5,R.id.button6}) void onButton4Clicked() {handleClick();};
    @Click({R.id.button7,R.id.button8,R.id.button9}) void onButton7Clicked() {handleClick();};
    @Click({R.id.button10,R.id.button11,R.id.button12}) void onButton10Clicked() {handleClick();};
    @Click(R.id.button13) void onButton13Clicked() {handleClick();};
    @Click(R.id.button14) void onButton14Clicked() {handleClick();};
    @Click(R.id.button15) void onButton15Clicked() {handleClick();};

    private void handleClick(){
        Toast.makeText(this, "AndroidAnnotations are cool!", Toast.LENGTH_SHORT).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.main, menu);
        return true;
    }
}


That's all. Hope you like it.

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†