Tuesday, September 22, 2015

[ButterKnife] Sum and Diff Simple Android App

Hello Guys!

 In Android development, One of the famous open source library  is Butterknife. What is ButterKnife? A Library that binds your Android views which uses annotation process. built by Jake Wharton.
- Very light weight.
- Eliminates long codes in finding your Android views.
- It uses annotation such as @Bind, @OnClick and more.
- Clean code and organize.
- Binds String resources.

Personally I always includes this library in most of my projects , I highly recommend you guys to use this, it will improve your speed in production.

 you can add this library using Gradle system of Android studio

dependencies {
   compile 'com.jakewharton:butterknife:7.0.1'
}

After syncing your Gradle, you can now use Butterknife in your project.

Here's My Example Android App that can get the Sum or Diff of two numbers.

1.MainActivity.java
package com.example.uge.butterknifesample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

    @Bind(R.id.firstNum)
    EditText firstNum;

    @Bind(R.id.secondNum)
    EditText secondNum;


    @Bind(R.id.answerText)
    TextView answerTxt;

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

    }

    @OnClick(R.id.sumBtn)
    void getTheSumOfTwoNumbers(){
        if(validateEditText()){
            int fValue = Integer.parseInt(firstNum.getText().toString());
            int sValue = Integer.parseInt(secondNum.getText().toString());
            int sumValue = fValue + sValue;
            answerTxt.setText("Sum: " + sumValue);
        }else{
            Toast.makeText(this, "Please Input the Values in the EditText(s)", Toast.LENGTH_SHORT).show();
        }
        hideKeyboard();
    }

    @OnClick(R.id.diffBtn)
    void getTheDiffOfTwoNumbers(){
        if(validateEditText()){
            int fValue = Integer.parseInt(firstNum.getText().toString());
            int sValue = Integer.parseInt(secondNum.getText().toString());
            int diffValue = fValue - sValue;
            answerTxt.setText("Diff: " + diffValue);
        }else{
            Toast.makeText(this, "Please Input the Values in the EditText(s)", Toast.LENGTH_SHORT).show();
        }
        hideKeyboard();
    }

    public Boolean validateEditText(){
        //The Two EditText must have a value
        if(firstNum.getText().toString().length() > 0 && secondNum.getText().toString().length() > 0){
            return true;
        }else{
            return false;
        }
    }

    public void hideKeyboard(){
        InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        if(imm.isAcceptingText()) { // verify if the soft keyboard is open
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
    }

}


2. Layout (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:layout_margin="15dp"
    tools:context="com.example.uge.butterknifesample.MainActivity">

    <EditText
        android:id="@+id/firstNum"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:inputType="number"
        android:hint="First Number" />

    <EditText
        android:id="@+id/secondNum"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:hint="Second Number"
        android:inputType="number"
        android:layout_below="@+id/firstNum" />

    <Button
        android:id="@+id/sumBtn"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:text="Sum"
        android:layout_below="@+id/secondNum"
        android:layout_margin="5dp"/>
    <TextView
        android:id="@+id/orText"
        android:layout_below="@+id/sumBtn"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="OR"
        android:layout_margin="5dp"/>
    <Button
        android:id="@+id/diffBtn"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:text="Difference"
        android:layout_below="@+id/orText"
        android:layout_margin="5dp"/>


    <TextView
        android:id="@+id/answerText"
        android:textSize="20sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>


Here's the OUTPUT:


 


You can download the sources code here: ButterknifeSample


for automation of binding views in Butterknife you can use Butterknife zelezny

Sunday, September 13, 2015

Downloading Bulk Images in Android

Hello Android Geeks,

Recently, I got an Android app project in my current work, Wherein the App needs to download bulk images via Webservices/API,
and the requirement of the process of downloading the assets is must be synchronous.

Here's is the sample code that I made to showcase the Android Library of NOSTRA13
entitle "Android-Universal-Image-Loader". for more info about this visit his GITHUB REPO

1.Download and compile the UIL in the Gradle's dependency
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'
}


2.Setup your Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sample.xeugene.imagedownload" >

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

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>


3. MainActivity
package com.sample.xeugene.imagedownload;

import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.nostra13.universalimageloader.core.ImageLoader;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    final static String TAG = &quot;MAIN_ACTIVITY&quot;;
    ImageLoader imageLoader;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageLoader = ImageLoader.getInstance();

        new DownloadThisImageFromUrl().execute();

    }
    //Running the method imageloader.loadImagesync() must be
    // run in the background thread of the App.
    public class DownloadThisImageFromUrl extends AsyncTask&lt;String, String ,String&gt; {
        @Override
        protected String doInBackground(String... strings) {
            for(String urls : listOfUrls()) {
                Bitmap image = imageLoader.loadImageSync(urls);
                Log.d(TAG, &quot;Download Success: &quot; + image);
                //You can use this var image to save in your SQLite DB :)
            }
            return null;
        }
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Log.d(TAG, &quot;DOWNLOAD COMPLETE!&quot;);
        }
    }

    //Static list url of the Images
    //You can add your desired Images here :)
    public List&lt;String&gt; listOfUrls(){
        List&lt;String&gt; listUrl = new ArrayList&lt;&gt;();
        listUrl.add(&quot;http://dogzone.tcwebsites.netdna-cdn.com/wp-content/uploads/2015/01/Funny-dog-names.jpg&quot;);
        listUrl.add(&quot;http://dreamatico.com/data_images/dog/dog-5.jpg&quot;);
        listUrl.add(&quot;http://static.communitytable.parade.com/wp-content/uploads/2014/02/labrador-america-top-dog-breed-ftr.jpg&quot;);
        return  listUrl;
    }
}


4. Instantiate the Universal Image Loader library in the Application (Singleton)
package com.sample.xeugene.imagedownload;

import android.app.Application;
import android.content.Context;

import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;

/**
 * Created by EugeneAllen on 9/22/2015.
 */
public class App extends Application {


    @Override
    public void onCreate() {
        super.onCreate();

        initImageLoader(getApplicationContext());
    }

    public static void initImageLoader(Context context) {
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheOnDisc(true).cacheInMemory(true)
                .imageScaleType(ImageScaleType.EXACTLY)
                .displayer(new FadeInBitmapDisplayer(300)).build();

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                context)
                .defaultDisplayImageOptions(defaultOptions)
                .memoryCache(new WeakMemoryCache())
                .discCacheSize(100 * 1024 * 1024).build();

        ImageLoader.getInstance().init(config);
    }
}

Using Shared Preferences in Setting Screen

Hi Guys I'm back! Today, My topic is all about Shared Preferences of Android. What is Shared Preference? a class that allows you to save and retrieve persistent key-value pairs of primitive data types(booleans, floats, ints, longs, and strings). This sample code may give you idea how to use Shared Preference in your Android App Projects. I used Shared Preference in saving my Settings, The scenario is if the user wants to save his/her setting in the app for example, turning on/ turning off the Music, Sounds and Updates. Note: This data will persist across user sessions (even if your application is killed).

import android.app.Activity;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Switch;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {

    Switch musicSwitch;
    Switch soundsSwitch;
    Switch updatesSwitch;

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

        musicSwitch = (Switch) findViewById (R.id.switch1);
        soundsSwitch = (Switch) findViewById (R.id.switch2);
        updatesSwitch = (Switch) findViewById (R.id.switch3);
        saveBtn = (Button) findViewById (R.id.buttonSave);

        setWidget();
        saveBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                savePreferences();
            }
        });

    }

    private void setWidget(){
        //Get the value of SharedPref if null return false 
        SharedPreferences customSharedPreference = getSharedPreferences("mySettings", Activity.MODE_PRIVATE);
        updatesSwitch.setChecked(customSharedPreference.getBoolean("updates",false));
        musicSwitch.setChecked(customSharedPreference.getBoolean("music",false));
        soundsSwitch.setChecked(customSharedPreference.getBoolean("sounds",false));


    }
    private void savePreferences(){

        SharedPreferences myPref = getSharedPreferences("mySettings", Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = myPref.edit();
        //Setting the value of SharedPref
        editor.putBoolean("music", musicSwitch.isChecked());
        editor.putBoolean("sounds", soundsSwitch.isChecked());
        editor.putBoolean("updates", updatesSwitch.isChecked());
        editor.commit();

        Toast.makeText(this, "Setting Saved", Toast.LENGTH_SHORT).show();
    }

}



Layouts:
<RelativeLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <Switch android:id="@+id/switch1"
        android:layout_centerInParent="true"
        android:layout_height="20dp"
        android:layout_width="wrap_content"
        android:text="Music"/>

    <Switch android:id="@+id/switch2"
        android:layout_height="20dp"
        android:layout_width="wrap_content"
        android:text="Sounds"
        android:layout_above="@+id/switch3"
        android:layout_alignLeft="@+id/switch3"
        android:layout_alignStart="@+id/switch3"
        android:layout_marginBottom="56dp" />


    <Switch android:id="@+id/switch3"
        android:layout_height="20dp"
        android:layout_width="wrap_content"
        android:text="Updates"
        android:layout_above="@+id/switch1"
        android:layout_alignLeft="@+id/switch1"
        android:layout_alignStart="@+id/switch1"
        android:layout_marginBottom="49dp" />

    <Button android:id="@+id/buttonSave"
        android:layout_height="45dp"
        android:layout_width="80dp"
        android:text="SAVE"
        android:layout_below="@+id/switch1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="58dp" />

</RelativeLayout>
Output: