Code snippets for rapid prototyping of Android Studio apps

This is a list of Android code examples I’m starting to allow me to create rapid prototypes of Android applications using Android Studio. This is a very early list, I hope to be adding many more Android code snippets over time.

Convert a list of strings to a string

List<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
list.add("baz");
String joined = TextUtils.join(", ", list);

Show a popup dialog with a textfield/edittext

private void showAddItemDialog(Context c) {
    final EditText taskEditText = new EditText(c);
    AlertDialog dialog = new AlertDialog.Builder(c)
        .setTitle("Add a new task")
        .setMessage("What do you want to do next?")
        .setView(taskEditText)
        .setPositiveButton("Add", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String task = String.valueOf(taskEditText.getText());
            }
        })
        .setNegativeButton("Cancel", null)
        .create();
    dialog.show();
}

Set a click listener (tap listener) on a Button

Java:

 protected void onCreate(Bundle icicle) {
     super.onCreate(icicle);
     setContentView(R.layout.my_layout_id);

     final Button button = (Button) findViewById(R.id.my_cool_button);
     button.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
             // your handler code here
         }
     });
 }

More:

Set a spinner (drop down list) data programmatically

Java:

// https://alvinalexander.com/source-code/how-set-android-spinner-data-array-from-java
Spinner qbSpinner1 = (Spinner)qbTableLayout.findViewById(R.id.spinner1);
List<Integer> spinnerArray = new ArrayList<>();
spinnerArray.add(10);
spinnerArray.add(11);
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(
    getActivity(),
    android.R.layout.simple_spinner_item,
    spinnerArray
);
//adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
qbSpinner1.setAdapter(adapter);

XML:

// spinner (drop down) xml
<Spinner
    android:id="@+id/spinner1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:spinnerMode="dropdown" />

More:

  • https://alvinalexander.com/source-code/how-set-android-spinner-data-array-from-java

How to get values from spinners

Shows how to get values from spinners, and how to start intent/activity with extras

// https://alvinalexander.com/source-code/android-button-listener-spinners-intent-extras
private void addButtonListener(Button playGameButton) {
    playGameButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String yourTeamName = String.valueOf(mYourTeamSpinner.getSelectedItem());
            String opponentTeamName = String.valueOf(mComputerTeamSpinner.getSelectedItem());
            Intent intent = new Intent(getActivity().getApplicationContext(), PlayGameActivity.class);
            intent.putExtra(YOUR_TEAM_NAME, yourTeamName);
            intent.putExtra(OPPONENT_TEAM_NAME, opponentTeamName);
            startActivity(intent);
        }
    });
}

More about spinners with static strings in xml:

  • http://www.ahotbrew.com/android-dropdown-spinner-example/
  • https://www.mkyong.com/android/android-spinner-drop-down-list-example/

Static string array

A static string array in an Android XML file, such as res/values/strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="my_books">
        <item>Scala Cookbook</item>
        <item>Play Framework Recipes</item>
        <item>How I Sold My Business: A Personal Diary</item>
        <item>A Survival Guide for New Consultants</item>
    </string-array>
</resources>

Create a Java string array from that XML in an activity or fragment:

Resources res = getResources();
String[] myBooks = res.getStringArray(R.array.my_books);

More:

Toasts and Snackbars

Simple toast:

Toast.makeText(getActivity(), "Click!", Toast.LENGTH_SHORT).show();

With gravity:

Toast t = Toast.makeText(getActivity(), "Click!", Toast.LENGTH_LONG);
t.setGravity(Gravity.TOP, 0, 0); 
t.show();

Snackbar:

Snackbar.make(
    view, 
    "going to: " + url, 
    Snackbar.LENGTH_LONG
).show();

Start a new activity

Regular:

Intent i = new Intent(getActivity(), ImagePagerActivity.class);
startActivity(i);

One line:

startActivity(new Intent(getActivity(), ImagePagerActivity.class));

With an extra:

Intent i = new Intent(getActivity(), ImagePagerActivity.class);
i.putExtra("POSITION", position);
startActivityForResult(i, 0);

Android threads

With Runnable:

Runnable runnable = () -> { 
    // your code here ...
};
Thread t = new Thread(runnable);
t.start();

Java 8:

Thread t = new Thread(() -> {
    // your code here ...
});

Java 8 lambda:

new Thread(() -> // your code here).start();

More:

  • https://alvinalexander.com/android/android-cheat-sheet-main-concepts#toc_threads

Android AsyncTask

Example:

//                                              <Params, Progress, Result>
private class DeleteImagesTask extends AsyncTask<Void,   Void,     Void> {

    @Override
    protected Void doInBackground(Void... params) {
        // this might take a while ...
        deleteSelectedGalleryItems();
        return null;
    }

    @Override
    protected void onPostExecute(Void param) {
        galleryItemAdapter.notifyDataSetChanged();
    }
}

Run/execute that code:

new DeleteImagesTask().execute();

More:

Android RecyclerView

See:

  • https://antonioleiva.com/recyclerview/
  • https://code.tutsplus.com/tutorials/getting-started-with-recyclerview-and-cardview-on-android--cms-23465
  • https://developer.android.com/training/material/lists-cards.html
  • https://www.androidhive.info/2016/01/android-working-with-recycler-view/

Handling a FloatingActionButton click/tap

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();
    }
});

SingleFragmentActivity, Activity, and Fragment

An Activity that uses a Fragment:

import android.app.Fragment;

/**
 * Let the user add a new quote.
 */
public class NewQuoteActivity extends SingleFragmentActivity {

    @Override
    protected Fragment createFragment() {
        //String theQuote = (String)getIntent().getStringExtra(NewQuoteFragment.KEY_QUOTE_EXTRA);

        // note: this is no longer needed, though the docs say it is
        //getActionBar().setDisplayHomeAsUpEnabled(true);
        return NewQuoteFragment.newInstance();
    }

}

The Fragment to go with Activity:

import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

/**
 * The logic to let the user add a new quote.
 */
public class NewQuoteFragment extends Fragment {

    private static final String TAG = "VPNewQuoteFragment";
    private EditText quoteTextField;
    private CheckBox pinQuoteCheckbox;

    public static NewQuoteFragment newInstance() {
        // doing this causes onCreate & co. to be run
        return new NewQuoteFragment();
    }

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

        // need this to enable the ability to respond to the user tapping the Back/Up icon
        setHasOptionsMenu(true);

        // use a custom "check" mark icon instead of the default Back/Up icon
        ActionBar actionBar = getActivity().getActionBar();
        actionBar.setIcon(R.drawable.ic_action_done_black_5a);
        actionBar.setDisplayHomeAsUpEnabled(false);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.edit_quote_fragment, parent, false);
        quoteTextField = (EditText)view.findViewById(R.id.quoteTextArea);
        pinQuoteCheckbox = (CheckBox)view.findViewById(R.id.pinQuoteCheckBox);
        return view;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                ...
                if (wasSavedSuccessfully) {
                    return true;
                } else {
                    return false;
                }
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    /**
     * handle the case where the user tapped the 'save' icon.
     * returns `true` if the quote was saved successfully, or if the string the user supplied was empty.
     */
    private boolean handleSaveProcess() {
        try {
            DatabaseManager.get(getActivity()).insertQuote(newQuote);
            if (pinQuoteCheckbox.isChecked()) {
                handleUserPinnedTheQuote(newQuote);
            }
            // i don't know if this is right, but it works. requires 'parent' setting in manifest.
            NavUtils.navigateUpFromSameTask(getActivity());
            return true;
        } catch (Throwable t) {
            //Log.e(TAG, "=== DATABASE ERROR ===");
            Toast.makeText(getActivity(), R.string.err_duplicate_quote, Toast.LENGTH_LONG).show();
            return false;
        }
    }

    private void handleUserPinnedTheQuote(String newQuote) {
        GlobalState.currentlyDisplayedQuote = newQuote;
        PreferencesUtils.handleUserPinsQuoteAction(getActivity().getBaseContext(), GlobalState.currentlyDisplayedQuote);
    }

}

The SingleFragmentActivity class, from the book, Android Programming: The Big Nerd Ranch Guide (might be slightly modified, such as with R.id.putYourFragmentHere):

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;

/**
 * Per the http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html javadoc:
 * If you want to implement an activity that includes an action bar,
 * you should instead use the ActionBarActivity class, which is a subclass of this one,
 * so allows you to use Fragment APIs on API level 7 and higher.
 */
public abstract class SingleFragmentActivity extends Activity {

    protected abstract Fragment createFragment();

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

        // set the view to our simple "single fragment" container
        setContentView(R.layout.single_fragment_container);

        FragmentManager fragmentManager = getFragmentManager();
        Fragment fragment = fragmentManager.findFragmentById(R.id.putYourFragmentHere);

        if (fragment == null) {
            fragment = createFragment();
            fragmentManager.beginTransaction()
                    .add(R.id.putYourFragmentHere, fragment)
                    .commit();
        }
    }

}

The XML (res/layout/singlefragmentcontainer.xml):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/putYourFragmentHere"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
/>

“About” Fragment (String in WebView)

Shows a simple way to display a String in a WebView:

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;

public class AboutFragment extends Fragment {

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_about, parent, false);

        String htmlAsString = getString(R.string.about_html);
        WebView webView = (WebView) v.findViewById(R.id.aboutWebView);
        webView.loadDataWithBaseURL(null, htmlAsString, "text/html", "utf-8", null);

        return v;
    }
}

WebView in an AlertDialog

A WebView component in an Android AlertDialog:

private void handleInfoButtonPressed() {
    DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int choice) {
            switch (choice) {
                case DialogInterface.BUTTON_NEUTRAL:
                    break;
            }
        }
    };

    // create a WebView with the current stats
    WebView webView = new WebView(context);
    webView.loadData(SampleStats.boxScore1, "text/html", "utf-8");

    // display the WebView in an AlertDialog
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setTitle("Stats (Sample)")
           .setView(webView)
           .setNeutralButton("OK", dialogClickListener)
           .show();

}

More:

Notification utilities

An Android Notification utilities class I used:

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

public class NotificationUtils {

    private static final String TAG = "VPNotificationUtils";

    /**
     * Documentation on setting alarms:
     * https://developer.android.com/training/scheduling/alarms.html
     */
    public static void startBackgroundNotifications(Context context,
                                                    AlarmManager alarmManager,
                                                    long notificationTimeIntervalInMillis) {
        PendingIntent pendingIntent = getPendingIntent(context);

        // 1) elapsed real time is recommended for this use. see https://developer.android.com/training/scheduling/alarms.html#set
        // 2) the second param is `triggerAtMillis`, ie, the trigger time. if it has the current time or past
        // time an alarm will be sent immediately. generally i don't think this is what i want, so i set it
        // to the future.
        alarmManager.setRepeating(AlarmManager.RTC,
                System.currentTimeMillis() + notificationTimeIntervalInMillis,
                notificationTimeIntervalInMillis,
                pendingIntent);
    }

    public static void turnOnNotifications(Context context) {
        long notificationTimeIntervalInMinutes = PreferencesUtils.getNotificationIntervalInMinutesFromPrefs(context);
        long notificationTimeIntervalInMillis = PreferencesUtils.convertMinutesToMilliseconds(notificationTimeIntervalInMinutes);
        startBackgroundNotifications(context, getAlarmManager(context), notificationTimeIntervalInMillis);
    }

    /**
     * per p. 473 of the big nerd book, this should turn off future alarms
     */
    public static void turnOffNotifications(Context context) {
        // i don't think this will ever be null, but ...
        PendingIntent pi = getPendingIntent(context);
        if (pi != null) {
            AlarmManager alarmManager = getAlarmManager(context);
            alarmManager.cancel(pi);
            pi.cancel();
        }
    }

    private static PendingIntent getPendingIntent(Context context) {
        Intent i = new Intent(context, PollingService.class);
        return PendingIntent.getService(context, 0, i, 0);
    }

    private static AlarmManager getAlarmManager(Context context) {
        return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    }

}

ListActivity and ListView

While the RecyclerView is generally preferred, the ListActivity/ListView approach still works as a means to show a scrolling list of items.

Java code:

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class TwitterClient extends ListActivity {

  // confirmed that scrolling works
  String[] values = { "Stream", "My Lists", "My Searches", "Trends",
      "Foo", "Bar", "Baz", "Foobar", "Barbaz", "aaa", "bbb", "abc",
      "123", "234", "456", "567", "678"
  };

  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.mainmenu);

      // parameters are (Context, layout for the row, and the array of data)
      setListAdapter(new ArrayAdapter<String>(this,
          android.R.layout.simple_list_item_1, values));
  }

  @Override
  protected void onListItemClick(ListView l, View v, int position, long id) {
      String item = (String) getListAdapter().getItem(position);
      Toast.makeText(this, item + " selected", Toast.LENGTH_LONG).show();
  }

}

XML file (mainmenu.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" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

More:

How to create and extend a custom View

A custom View to draw a rectangle:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.View;

public class CustomView extends View {

    private Rect rectangle;
    private Paint paint;

    public CustomView(Context context) {
        super(context);
        int x = 50;
        int y = 50;
        int sideLength = 200;

        // create a rectangle that we'll draw later
        rectangle = new Rect(x, y, sideLength, sideLength);

        // create the Paint and set its color        
        paint = new Paint();
        paint.setColor(Color.GRAY);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLUE);
        canvas.drawRect(rectangle, paint);
    }

}

Use the custom View in an Activity:

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new CustomView(this));
    }

}

More: