Source code snippets (examples)

This is a list of Alvin Alexander's source code snippets (simple source code examples).

Android EditText isScrollContainer example (how to make multiline EditText scrolling)

I just added an editable EditText widget to an Android application, and I needed to make the EditText a certain height, and also make the text in the EditText scroll, in case the user added some really long text. I used the following XML in my Android layout to make this happen:

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="textMultiLine"
    android:ems="10"
    android:id="@+id/quoteTextArea"
    android:editable="true"
    android:enabled="true"
    android:minLines="6"
    android:maxLines="6"
    android:isScrollContainer="true"
    android:hint="Type your quote here"
    android:background="#fafafa"
    android:textIsSelectable="true"
    android:focusable="true"
    android:gravity="top"
    android:padding="24dp"
    style="@style/Base.TextAppearance.AppCompat.Large"
    />

For the stated purposes, these are the most important lines in that EditText XML:

android:inputType="textMultiLine"
android:editable="true"
android:enabled="true"
android:minLines="6"
android:maxLines="6"
android:isScrollContainer="true"
android:focusable="true"

This displays an EditText field that the user can type into, and if they type some text that’s really long, the EditText widget will automatically scroll. (As a result, the EditText field won’t keep getting larger, and hide the text under the keyboard -- and that’s a good thing.)

An Android CheckBox OnClickListener example (and identityHashCode)

Here’s some source code that shows how to add an Android OnClickListener to a CheckBox:

checkBox.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.i(TAG, String.format("checkbox onClick, isSelected: %s, identityHashCode: %s", checkBox.isSelected(), System.identityHashCode(checkBox)));
    }
});

The OnClickListener code is straightforward, so I won’t explain it; I’m just putting it here so I can find it easily in the future, like a code snippet manager.

One other thing to note is the use of the identityHashCode. I did that because I was having a weird problem working with Android checkboxes. The short story is that I kept trying to use the isSelected method on each CheckBox, which I should have been using isChecked. I used the identityHashCode method to help troubleshoot the problem.

An Android AlertDialog yes/no choice example (and OnClickListener)

Here’s a source code snippet that shows how to create an Android AlertDialog. If I remember right, I got the initial code from Stack Overflow, and then adapted it for my need, which was to confirm that the user wanted to delete an image from an image gallery:

DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int choice) {
        switch (choice) {
            case DialogInterface.BUTTON_POSITIVE:
                try {
                    String rootDir = FileUtils.getImagesDir(getActivity());
                    boolean fileWasDeleted = FileUtils.deleteFile(rootDir + "/" + imageFilename);
                    if (fileWasDeleted) {
                        Toast.makeText(getActivity(), "The file was deleted", Toast.LENGTH_SHORT).show();
                    }
                } catch (IOException ioe) {
                    // TODO let the user know the file couldn't be deleted
                }
                break;
            case DialogInterface.BUTTON_NEGATIVE:
                break;
        }
    }
};

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Delete this image?")
        .setPositiveButton("Yes", dialogClickListener)
        .setNegativeButton("No", dialogClickListener).show();

If you understand Android programming this code should be pretty straightforward, so I won’t explain it here, other than to say that it looks like typical Java/Android “listener” style programming.

Java source code to get the extension from a filename

While writing some Java code today, I needed a method to get the extension from a filename. This code solved the problem:

public static String getFilenameExtension(String filename) {
    String extension = "NoExtension";
    int i = filename.lastIndexOf('.');
    if (i > 0) {
        extension = filename.substring(i + 1);
    }
    return extension;
}

Given an input filename like foo.jpg, the getFilenameExtension method returns the “jpg” part as a String.

Warning: I have no idea what this method will do if you pass a null value to it. Don’t do that. (I write my code without null values these days, so I don’t think or account for situations like that.)

A Swift sliderChanged method (handling the Value Changed event)

I’ve seen a few approach to handling a Swift “Value Changed” event, but when you’re only interested in whole number (50, 51, etc.), this approach seems the simplest:

// comes from the Value Changed event
@IBAction func sliderChanged(sender: UISlider) {
    let sliderValue = lroundf(sender.value) //50, 51, ...
    // do something with `sliderValue` ...
}

I’ve seen people take different approaches to get the slider value, but this approach that uses the lroundf method seems the simplest. With this line of code, sliderValue ends up being an Int.

Android: How to create a new Fragment and put it in a layout

I’ve been working on an Android app that uses a navigation drawer, and uses fragments for each item in the drawer that you tap on. One of the items in the nav drawer is a “Preferences” item, so when I tap on that item, I run the following code from my nav drawer code:

Fragment prefsFragment = new PreferencesFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, prefsFragment).commit();

What this does is create a new instance of my PreferencesFragment, and then puts that fragment into what I call the content_frame. This content_frame refers to a FrameLayout that I’ve defined in my activity_main.xml layout file. This fragment basically replaces whatever else was in that FrameLayout before this call. I believe this is the correct approach, at least with the navigation drawer code that I’m using.

My main layout file

For the record, my activity_main.xml file currently looks like this:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#d0111111"/>

</android.support.v4.widget.DrawerLayout>

I made the FrameLayout tag bold in that file; that’s where all of my fragments are placed when I run the code I showed above.

When is a Fragment destroyed?

This code just made me wonder, “When is this fragment destroyed?” To test this I added an onDestroy() method to my fragment and logged a message when it was destroyed. onDestroy is actually called as soon as I switch to another fragment via my Navigation Drawer interface. That’s good to know.

Here’s a link to the official Android Fragments documentation page. Here’s another link to a useful article that discusses the fragment lifecycle, and shares some source code via Github to demonstrate it all.

MAMP Apache httpd.conf configuration with ProxyPass and ProxyPassReverse

As a quick note to self, I used this Apache httpd.conf configuration in MAMP on my MacBook Pro when developing my “Focus” web application in 2014:

<VirtualHost 127.0.0.1>
    ServerName focus
    ProxyPass /server http://localhost:8080
    ProxyPassReverse /server http://localhost:8080
    DocumentRoot /Applications/MAMP/htdocs/focus
    <Directory /Applications/MAMP/htdocs/focus>
        DirectoryIndex index.php index.html
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

Looking at this in 2015 I stared at that config for a little while, wondering why I used ProxyPass and ProxyPassReverse settings, and then remembered that Focus was written with Sencha, and it used a Play Framework backend, and Sencha (generally speaking) needs to communicate with a server on the same domain as its website. By default, MAMP runs on port 8888, and I had the Play server running on port 8080.

FWIW, I also had this entry in my /etc/hosts file:

127.0.0.1    focus localhost

So that’s what those settings are about.

Android: Notes on using a PreferenceFragment with the Google Navigation Drawer code (Fragment lifecycle methods)

These are some notes on what happens when I use a PreferenceFragment with the Google Navigation Drawer code.

These are the Fragment lifecycle methods that are run when I go to my PreferenceFragment the first time:

I/VPPreferencesFragment﹕ ENTERED onCreate
I/VPPreferencesFragment﹕ ENTERED onCreateView
I/VPPreferencesFragment﹕ ENTERED onViewCreated
I/VPPreferencesFragment﹕ ENTERED onActivityCreated
I/VPPreferencesFragment﹕ ENTERED registerPreferencesChangeListener
I/VPPreferencesFragment﹕ ENTERED onStart
I/VPPreferencesFragment﹕ ENTERED onResume

Then when I go back to the Navigation Drawer, and tap Preferences, I see these lifecycle methods:

I/VPPreferencesFragment﹕ ENTERED onPause
I/VPPreferencesFragment﹕ ENTERED onStop
I/VPPreferencesFragment﹕ ENTERED onDestroyView
I/VPPreferencesFragment﹕ ENTERED onDestroy
I/VPPreferencesFragment﹕ ENTERED onDetach
I/VPPreferencesFragment﹕ ENTERED onCreate
I/VPPreferencesFragment﹕ ENTERED onCreateView
I/VPPreferencesFragment﹕ ENTERED onViewCreated
I/VPPreferencesFragment﹕ ENTERED onActivityCreated
I/VPPreferencesFragment﹕ ENTERED registerPreferencesChangeListener
I/VPPreferencesFragment﹕ ENTERED onStart
I/VPPreferencesFragment﹕ ENTERED onResume

I used this log output to debug a specific problem today, but if you need to debug a Fragment's lifecycle methods, you can see from this example which lifecycle methods are called when a Fragment is first created, and then when the Fragment is reused.

How to launch an Activity with an Intent, while also passing "extra" data

Here’s a short example of how to use an Intent to launch an Android Activity, while also adding some data (an “extra”) to the activity-launching process:

Intent currentQuoteIntent = new Intent(this, LandingPageActivity.class);
currentQuoteIntent.putExtra(GlobalState.LANDING_PAGE_INTENT_KEY, GlobalState.);
startActivityForResult(currentQuoteIntent, 0);

I show how to get the “extra” from an Activity or Fragment in this article on How to attach an extra to an Intent/PendingIntent in a Notification., but in short, the receiving Activity/Fragment can access the extra data like this:

public static class ShowFullQuoteFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container,
                             Bundle savedInstanceState) {

        // get the 'extra'
        String quote = getActivity().getIntent().getStringExtra(PollingService.INTENT_KEY);
        Log.i(PF_TAG, "QUOTE: " + quote);

        // other code here ...
        View rootView = inflater.inflate(R.layout.fragment_show_full_quote, container, false);
        TextView quoteLabel = (TextView)rootView.findViewById(R.id.put_quote_here);
        quoteLabel.setText(quote);
        return rootView;
    }
}

If you wanted to see how to add an extra to an Intent, use the Intent to launch an Activity, and then access the Intent in an Activity or Fragment, I hope this code is helpful.

How to get the Android screen orientation (in Java code)

Use this code to get the Android screen orientation:

// orientation (either ORIENTATION_LANDSCAPE, ORIENTATION_PORTRAIT)
int orientation = getResources().getConfiguration().orientation;

As shown in the comment, the resulting orientation will either be ORIENTATION_LANDSCAPE or ORIENTATION_PORTRAIT. See the Android docs for more information.