Android

Custom Fragment Backstack in Android

Dealing with Fragments is always a pain: after some time I found a way to deal with them in a less painful way, creating a custom Fragment Backstack.

How to create your custom Fragment Backstack navigation

Put this code in your main Activity:

public class MainActivity extends AppCompatActivity {

    private Stack<Fragment> fragmentStack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragmentStack = new Stack<>();
    }

    @Override
    public void onBackPressed() {
        fragmentStack.pop();
        if (fragmentStack.size() == 0) {
            super.onBackPressed();
        } else {
            showFragment(fragmentStack.lastElement(), false);
        }
    }

    public void showFragment(Fragment fragment, boolean addToStack) {
        if (addToStack) {
            fragmentStack.push(fragment);
        }
        getFragmentManager().beginTransaction().replace(R.id.container_fragment, fragment).commit();
    }

}

We have a fragmentStack field which is a Stack of Fragment: we use this to save the Fragments we show in our app and we initialize it in the onCreate() method of the main Activity.

In the onBackPressed() method we remove the current Fragment from the Stack and then if there is another one, we show it, otherwise we close the app because there is nothing more to be shown.

The method showFragment() is the one we use to show a Fragment on the screen; we invoke it every time we need to change the visible Fragment. If we want to save the current transaction being able to come back to the current Fragment we pass true as addToStack value, otherwise we pass false.

Have a look at the full source code on my GitHub here.

Android

Auto hide keyboard using Android EditText

Do you want to automatically hide your keyboard whenever you touch outside it? Please continue reading and you will find out how to do it!

First, we will create our AutoHideKeyboardEditText class like the following:

public class AutoHideKeyboardEditText extends EditText {

    public AutoHideKeyboardEditText(Context context) {
        super(context);
        init();
    }

    public AutoHideKeyboardEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public AutoHideKeyboardEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    hideKeyboard(v);
                }
            }
        });
    }

    private void hideKeyboard(View view) {
        InputMethodManager inputMethodManager = (InputMethodManager)
            view.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }
}

Whatever Constructor is used, we set an onFocusChangeListener to hide the keyboard using the proper method if we touch outside the EditText area (if the focus is not anymore on it).

Afterwards, create a layout similar to this

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

being sure, whatever layout you want to use, to add clickable and focusableInTouchMode attributes with true value.

Now just add our AutoHideKeyboardTextView inside that layout. You can simply add it using XML like the following

<com.w3ma.androidshowcase.autohidekeyboard.AutoHideKeyboardEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

 

You are done! Whenever you touch outside the EditText the keyboard will be automatically dismissed!

Please note: you should add the clickable and focusableInTouchMode attributes to the outermost view but if it is a ScrollView this might not work. For such case, those attributes could be added to the view directly under the ScrollView.

Full source code on my GitHub repository here.

Source:https://stackoverflow.com/questions/4165414/how-to-hide-soft-keyboard-on-android-after-clicking-outside-edittext/19828165#19828165

I don’t know why this wasn’t voted as the best answer because it is indeed.

Android

Android Studio gitignore to avoid useless files

Create a perfect Android Studio .gitignore file is sometimes tedious, so I have gathered some information on the Internet, mainly on StackOverflow, I made some experiments with my sample project over and over and finally I obtained a perfect Android Studio .gitignore file.

Usually, I create my project inside a parent folder which I initialize as my Git repository.

So, for example, this is a sample structure (folders are bolded):

AndroidShowcaseRepository

  • .git
  • AndroidShowCase
    • .gradle
    • .idea
    • app
    • build
    • gradle
    • .gitignore
    • AndroidShowcase.iml
    • build.gradle
    • gradlew
    • gradlew.bat
    • local.properties
    • settings.gradle
  • .gitignore
  • LICENSE
  • README.md

I use the following as content for the .gitignore file in the AndroidShowcaseRepository folder

# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/

# Gradle files
.gradle/
build/
/*/build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

and the following as content for the .gitignore file in the AndroidShowcase folder

.gradle
/local.properties
.DS_Store
/build
/captures
.idea
gradlew
gradlew.bat
gradle

Using these two .gitignore files (and the default ones created by Android Studio inside the app folder and into other folders you could have) you will likely save only the necessary source code to your repository and not files which could be generated by Android Studio itself.

Check w3ma showcase repository for the complete source code and for more explanation!

Android

Making TextView with clickable link in Android

I will explain how to create a TextView with inside a clickable link in Android.

Do you want to open a static link without doing other operations? So just follow the first part of this tutorial! Otherwise, if you want to have more control on the link customization and operations after the user taps on it, follow the second part of the tutorial.

STATIC CLICKABLE LINK INSIDE STRINGS.XML RESOURCE

Let’s create an example TextView in your layout like this one:

<TextView
    android:id="@+id/messageWithLinkTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:gravity="center"
    android:text="@string/messageWithLink" />

Create this string in strings.xml:

<string name="messageWithLink">This is a message with a link inside!\n<a href="https://www.google.com/">Tap here to open it!</a></string>

Write this code in your activity/fragment:

@Bind(R.id.messageWithLinkTextView)
TextView messageWithLinkTextView;

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ButterKnife.bind(this, view);
    messageWithLinkTextView.setMovementMethod(LinkMovementMethod.getInstance());
}

Please note: I’m using ButterKnife library to bind fields and views (I suggest you to have a look at this fantastic library!)

You are done! You should get a TextView like the one in the following screenshot and when you tap on the hyperlink the browser should open! Cool!

textview_with_clickable_link

P.S. unfortunately I didn’t find a way of achieving this only using XML properties. If anyone knows how to do it, please let me know in the comments!

CUSTOM CLICKABLE LINK AND CUSTOM ACTIONS

Create another TextView in your layout:

<TextView
   android:id="@+id/messageWithSpannableLinkTextView"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerInParent="true"
   android:gravity="center"
   tools:text="@string/messageWithSpannableLink" />

Create another string resource in strings.xml:

<string name="messageWithSpannableLink">This is a message with a spannable link inside!\nTap here to open it!</string>

Please note: this time there is no <a href/> tag inside the string!

Now write this code in your activity/fragment:

@Bind(R.id.messageWithSpannableLinkTextView)
TextView messageWithSpannableLinkTextView;

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ButterKnife.bind(this, view);
    SpannableString spannableString = new SpannableString(getString(R.string.messageWithSpannableLink));
    ClickableSpan clickableSpan = new ClickableSpan() {
        @Override
        public void onClick(View textView) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com")));
        }
    };
    spannableString.setSpan(clickableSpan, spannableString.length() - 20,
            spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    messageWithSpannableLinkTextView.setText(spannableString, TextView.BufferType.SPANNABLE);
    messageWithSpannableLinkTextView.setMovementMethod(LinkMovementMethod.getInstance());
}

You are done! You should get a TextView like the one in the following screenshot and when you tap on the hyperlink the ClickableSpan->onClick() method should be called, so you can do your operations and let the browser open the link! Cool!

textview_with_spannable_clickable_link

Check out the complete source code on my GitHub here!

GNU/Linux

Assign static device name using udev rules

How can you assign static device name using udev rules to a USB device? Why do you need it?

Imagine you made a script which refers to a particular device you could plugin trough USB port: sometimes this device could be mounted as /dev/sdb1, sometimes as /dev/sdc1, and so on. You may need a static reference to it because you didn’t know which name it will use.

Another scenario could be a startup mount of a drive as discussed in http://www.w3ma.com/mount-ntfs-partition-startup/

To achieve this, let first discover some attributes of our device using the command

sudo lsusb

We will receive an output like this:

emanuele@ubuntu:~$ lsusb

Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Bus 001 Device 004: ID 1058:107c Western Digital Technologies, Inc.

Have a look at the Western Digital Technologies row, this is the device we are looking for: 1058 is the Vendor ID and 107c is the Product ID! We will use these information to uniquely identify our device.

Now, let’s create a new udev rule typing

sudo nano /etc/udev/rules.d/99-my_rules.rules

and writing the following into the file

ACTION==”add”, ATTRS{idVendor}==”1058″, ATTRS{idProduct}==”107c”, SYMLINK+=”my_wd_usb_hd”

where the ATTRS numbers are the ones we discovered before, while my_wd_usb_hd is the name we choose for our device.

Now let’s reboot our pc! Everytime it reboots this rule will be applied and we will always find our device under /dev/my_wd_usb_hd

GNU/Linux

Mount NTFS partition at startup

In this post we will learn how to mount NTFS partition at startup in a very simple way.

You can use the following command to retrieve a list of your partitions and their UUID.

ls -l /dev/disk/by-uuid

Pick the one you want to automatically mount and open the file /etc/fstab by using

sudo nano /etc/fstab

Add a new row like:

UUID=XXXXXXXXXXX  /hd_mount_point       ntfs-3g defaults        0       0

where XXXXXXXXXXX is your partition UUID and /hd_mount_point is a folder on your disk you will use to access that partition.

Simply reboot and you are done!

GNU/Linux

Force Ubuntu boot after power failure

Hello,

in this blog post I will show a little trick to avoid your Ubuntu installation got stuck on GRUB boot menu waiting for you to choose an option after a power failure.

To force Ubuntu boot you can edit your /etc/default/grub with your favourite text editor, e.g. running this command from your terminal:

nano /etc/default/grub

and then add this line in the file:

GRUB_RECORDFAIL_TIMEOUT=0

Afterwards, remember to run:

sudo update-grub

Next time your pc will have a power failure it will reboot without getting stuck on GRUB!