Thursday, May 18, 2017

Android Floating Action Button with animation part-2

May 18, 2017

Welcome to the part two of our today's android project.
In the previous part, we create animation XML and drawable. Now we add fab code in the layout. (if you miss part one click here)

In my case my layout is activity_main.xml before doing this we need two colors in colors.xml.
Let's add this
<color name="fab1">#e2e21d</color>
<color name="fab2">#47e92e</color>
Now add three fab button. I share this code one by one.
<android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="150dp"
        android:layout_marginEnd="16dp"
        android:layout_gravity="bottom|end"
        android:elevation="6dp"
        android:src="@drawable/ic_person_outline_black_24dp"
        app:fabSize="normal"
        android:visibility="gone"
        android:id="@+id/fab_people"
        app:backgroundTint="@color/fab2"
        app:pressedTranslationZ="12dp"/>
next one
<android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="80dp"
        android:layout_marginEnd="16dp"
        android:layout_gravity="bottom|end"
        android:elevation="6dp"
        android:src="@drawable/ic_school_black_24dp"
        app:fabSize="normal"
        android:visibility="gone"
        android:id="@+id/fab_school"
        app:backgroundTint="@color/fab1"
        app:pressedTranslationZ="12dp"/>
and the last one
<android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        android:layout_gravity="bottom|end"
        android:elevation="6dp"
        android:src="@drawable/ic_share_black_24dp"
        app:fabSize="normal"
        android:id="@+id/main_fab"
        app:pressedTranslationZ="12dp"/>

Note: if you have any dought you can check full activity.xml code on GitHub.

Now time for java code.
In my case java file is MainActivty.java Add those variables-
FloatingActionButton main,people,school;
Animation fabOpen,fabClose,fabRotate,fabRotateAntiClockWise;

//fab is open or close
boolean isOpen = false;
Now assign all fab button with findViewById()
main = (FloatingActionButton) findViewById(R.id.main_fab);
people = (FloatingActionButton) findViewById(R.id.fab_people);
school = (FloatingActionButton) findViewById(R.id.fab_school);
Now time for load animation-
fabOpen = AnimationUtils.loadAnimation(this,R.anim.fab_open);
fabClose = AnimationUtils.loadAnimation(this,R.anim.fab_close);
fabRotate = AnimationUtils.loadAnimation(this,R.anim.rotate_clockwise);
fabRotateAntiClockWise = AnimationUtils.loadAnimation(this,R.anim.rotate_anit_clockwise);

If the user clicks the main fab button then we will show others button. That's is the logic. ok add main fab clickListener and use below code to show others button. After the code, I discuss code logic again Ok enough talking. Let's start-

main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.e("Click", "click");

                if (isOpen){
                    people.setAnimation(fabClose);
                    school.setAnimation(fabClose);
                    main.setAnimation(fabRotateAntiClockWise);
                    people.setClickable(false);
                    school.setClickable(false);
                    people.setVisibility(View.GONE);
                    school.setVisibility(View.GONE);
                    isOpen = false;

                } else {
                    people.setVisibility(View.VISIBLE);
                    school.setVisibility(View.VISIBLE);
                    people.setAnimation(fabOpen);
                    school.setAnimation(fabOpen);
                    main.setAnimation(fabRotate);
                    people.setClickable(true);
                    school.setClickable(true);
                    people.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast.makeText(MainActivity.this, "Welcome to people", 
                                      Toast.LENGTH_SHORT).show();
                        }
                    });

                    school.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast.makeText(MainActivity.this, "Welcome to school", 
                                                      Toast.LENGTH_SHORT).show();
                        }
                    });

                    isOpen = true;
                }
            }
        });

Note: youcan recheck MainActivity.java on GitHub 

Code analysis-
1.In layout file when we created out floating action button we set those button's visibility gone excepts main fab button. we check boolean state first, isopen is true or false

2. If the answer is true that means fab is open now. So we set here close fab functionality.
2.1. set close animation on two fabs that are you want's to close.
2.2. set those fab clickable false.
2.3 set anti clock rotate animation on mainFab.
2.4 now time to invisible that's fab.
2.5 at last assign isopen to false.

3.If the answer is false that means fab is close. So we set here close fab functionality.
3.1. now time to invisible others fab.
3.1. set open animation on two fabs that are not shown.
3.2. set those fab clickable true.
3.3 set clock rotate animation on mainFab.
3.4 set click listener on those fab
3.5 at last assign isopen to true.

Wow. now we fab three fabs in our layout but only one is showing at first. After clicking main fab other's button is open with animation. And those button is now working. And again click the main fab button, others two buttons is gone. So welcome to you all. you successfully created this project.

you can find the full project on Github. Fab

Thanks for reading this post and hope this code is working and now you can use fab with animation on your own project.

Happy coding.

Read More

Android Floating Action Button with animation

May 18, 2017

In this android project, we create 3 floating action button. The main fab button is only showing when activity is launch. other's two are invisible. After clicking the main fab button it will show the other's fab button. Those buttons are now visible and clickable. after clicking again main fab button is rotate 45 degrees and close others fab button with animation. That's our main goal today.

Let's start to making our today's android app
First, add those dependencies to your build.gradle file
dependencies {
   
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support:design:25.2.0'
    
}

Now we create 4 animations XML file in res > anim folder.

1.fab_open.XML
2.fab_close.xml
3. rotate_clockwise.XML
4.rotate_anti_clockwise.xml

first two are using on closing and opening fab and last 2 are using to rotate the main fab.

Let's create those file in res > anim folder

Note: we should follow code comment. That will help us to understand code easily.

1.fab_open.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">
    <!-- android:fillAfter="true" is ensure thata animation transformation occur
     only after finish animation -->

    <!-- we change animation from 0 to 80 percent -->
    <!-- pivot x or y means it's is the center point of animation -->
    <scale
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:toXScale=".8"
        android:toYScale=".8"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration = "300"
        android:interpolator = "@android:anim/linear_interpolator"/>

    <!-- now change the animation of the opacity of the object -->
    <!-- now we change alpha 0 to 1 that's means object's disappears -->
    <!-- accelerate_interpolator means that's animation start's slowly -->
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"
        android:duration = "300"
        android:interpolator = "@android:anim/accelerate_interpolator"/>


</set>
2.fab_close.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">
    <!-- android:fillAfter="true" is ensure thata animation transformation occur
     only after finish animation -->

    <!-- same as fab_open.xml but inverse order -->
    
    <!-- we change animation from 80 to 0 percent -->
    <!-- pivot x or y means it's is the center point of animation -->
    <scale
        android:fromXScale=".8"
        android:fromYScale=".8"
        android:toXScale="0.0"
        android:toYScale="0.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration = "300"
        android:interpolator = "@android:anim/linear_interpolator"/>

    <!-- now change the animation of the opacity of the object -->
    <!-- now we change alpha 1 to 0 that's means object's disappears -->
    <!-- accelerate_interpolator means that's animation start's slowly -->
    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:duration = "300"
        android:interpolator = "@android:anim/accelerate_interpolator"/>

</set>
3.rotate_clockwise.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">

    <!-- it rotate to 0 to 45 degree -->

    <rotate
        android:fromDegrees="0"
        android:toDegrees="45"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration = "300"
        android:interpolator = "@android:anim/linear_interpolator"/>


</set>
34 rotate_anti_clockwise.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">

    <!-- same as clockwise.xml but inverse order -->
    <!-- in this animation we rotate start 45 to 0  -->
    <rotate
        android:fromDegrees="45"
        android:toDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration = "300"
        android:interpolator = "@android:anim/linear_interpolator"/>
</set>

Now add some drawable to on our android project. I am currently use vector drawable here. I also share my code here. Note you can use image or others vector drawable as you.(it also reduces android app size)

1.ic_person_outline_black_24dp.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M12,5.9c1.16,0 2.1,0.94 2.1,
        2.1s-0.94,2.1 -2.1,2.1S9.9,9.16 9.9,8s0.94,-2.1 2.1,
        -2.1m0,9c2.97,0 6.1,1.46 6.1,2.1v1.1L5.9,18.1L5.9,
        17c0,-0.64 3.13,-2.1 6.1,-2.1M12,4C9.79,4 8,5.79 8,
        8s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,13c-2.67,
        0 -8,1.34 -8,4v3h16v-3c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

2.ic_school_black_24dp.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M5,13.18v4L12,21l7,-3.82v-4L12,17l-7,-3.82zM12,3L1,9l11,6 9,-4.91V17h2V9L12,3z"/>
</vector>

3.ic_share_black_24dp.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,
        0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,
        -0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,
        0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,
        3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,
        9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,
        -0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,
        2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,
        -2.92 -2.92,-2.92z"/>
</vector>


Ok, that's looking great.
we have done a lot. In the next part, we have created layout and java code. Click here for next part.

Read More

Monday, May 15, 2017

Android Material Date picker Dialog

May 15, 2017

Welcome to this post.

In this post, we are going to create a material date picker.

Date picker Dialog helps you to pick the date for your application.
If you have an option for user pick their date then you can use it. This popup in your layout. SO it's won't take place on your layout. In this post, we learn about how we can use Date picker Dialog and pick our date.

Ok, let's started.
First, you need to create a class name here DatePickerFragment and extend to DialogFragment and implement DatePickerDialog.OnDateSetListener

Let me show-
public class DatePickerFragment extends DialogFragment implements
  DatePickerDialog.OnDateSetListener {

}

now override two methods named onCreateDialog and onDateSet. in onCreateDialog, we add a calendar and get current date from our calendar and return those values-

@Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {

  Calendar c = Calendar.getInstance();

  int startYear = c.get(Calendar.YEAR);
  startMonth = c.get(Calendar.MONTH);
  int startDay = c.get(Calendar.DAY_OF_MONTH);

  return new DatePickerDialog(getActivity(),this,startYear,startMonth,startDay);
  }

Note: in this methods, you can set you desire date if you want to show to your user. For this, you can first set date on the calendar the before getting data.

A quick look-
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);
  try {
  String dateStr = "1/5/2017";
  Date date = format.parse(dateStr);
  c.setTime(date);
  } catch (ParseException e) {
  e.printStackTrace();
  }

Note: here I formatted a string into date and set it to the calendar. But you can add directly like this way-

Calendar calendar =Calendar.getInstance();
        
calendar.set(Calendar.YEAR, 2017);
calendar.set(Calendar.MONTH, 2);
calendar.set(Calendar.DAY_OF_MONTH, 17);

when user set the date then onDateSet will be executed. the code is your wish. you get all in an integer. here I save it on shared preference.

@Override
  public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {

  String dateStr = dayOfMonth+"/"+month+"/"+year;
  SharedPreferences preferences = getActivity().getSharedPreferences("TimeDate", Context.MODE_PRIVATE);
  
  SharedPreferences.Editor editor = preferences.edit();
  editor.putString("Date",dateStr);
  editor.apply();

  }

Ok. we created our DatepickerDialog.java class. Now we use it on on button listener.

dateTvLabel.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
  DatePickerFragment datePickerFragment = new DatePickerFragment();
  datePickerFragment.show(getFragmentManager(), "Date Picker");
  }
  });

and That's it. Now you can use this Date Picker Dialog and customize your project.

datePicker


 Happy coding.

Read More

Android Material Time Picker Dialog

May 15, 2017

Time picker Dialog helps you to pick the time for your application. If you have an option for user pick their time then you can use it. This popup in your layout. SO it's won't take place on your layout. In this post, we learn about how we can use time picker Dialog and pick our time. First, you need to create a class name here TimePickerFragment and extend to DialogFragment and implement TimePickerDialog.OnTimeSetListener ok, Let's start -

public class TimePickerFragment extends DialogFragment implements
  TimePickerDialog.OnTimeSetListener {

}

now override two methods named onCreateDialog and onTimeSet. in onCreateDialog, we add a calendar and get the current time from our calendar and return those values-

@Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {

  //Use the current time as the default values for the time picker
  final Calendar c = Calendar.getInstance();

  int hour = c.get(Calendar.HOUR_OF_DAY);
  int minute = c.get(Calendar.MINUTE);

  //Create and return a new instance of TimePickerDialog
  return new TimePickerDialog(getActivity(), this, hour, minute,
  DateFormat.is24HourFormat(getActivity()));
  }

Note if you want to set a specific time then set on it calendar first and get date same as we do on DatePickerDiolog Ok, let's show again-

SimpleDateFormat format = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);

String timeStr = "10:12 PM"

try {
Date time = format.parse(timeStr);
c.setTime(time);
} catch (ParseException e) {
e.printStackTrace();
}

Note: here I formatted a string into date and set it to the calendar. But you can add directly like this way-

Calendar calendar =Calendar.getInstance();
  
calendar.set(Calendar.HOUR_OF_DAY, 22);
calendar.set(Calendar.MINUTE, 22);

when user set the date then onDateSet will be executed. code is your wish. you get all in an integer. here I save it on shared preference.

@Override
  public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
  String time=hourOfDay+":"+minute;
  SharedPreferences preferences = getActivity().getSharedPreferences("TimeDate", 
                                           Context.MODE_PRIVATE);
  SharedPreferences.Editor editor = preferences.edit();
  editor.putString("Time",time);
  editor.apply();
  }

That's it. we finished up TimePiclerDialog Class. But one this if you want to 12 our clock that's show AM or PM. Then you should modify this code. Because here hourOfDay is shown 24 hours format. Ok now modify the code. If our hourOfDay is greater than 11 then it's must be PM. so we add pm on the string. and subtract from 12 then we get again 12 hours format. Let's move on code-

//Get the AM or PM for current time
        String aMpM = "AM";
        if (hourOfDay > 11) {
            aMpM = "PM";
        }

        //Make the 24 hour time format to 12 hour time format
        int currentHour;
        if (hourOfDay > 11) {
            currentHour = hourOfDay - 12;
        } else {
            currentHour = hourOfDay;
        }

        String time = String.valueOf(currentHour)
                + ":" + String.valueOf(minute) + " " + aMpM;

Not enough for understanding then full methods-

@Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

        //Get the AM or PM for current time
        String aMpM = "AM";
        if (hourOfDay > 11) {
            aMpM = "PM";
        }

        //Make the 24 hour time format to 12 hour time format
        int currentHour;
        if (hourOfDay > 11) {
            currentHour = hourOfDay - 12;
        } else {
            currentHour = hourOfDay;
        }

        String time = String.valueOf(currentHour)
                + ":" + String.valueOf(minute) + " " + aMpM;

        Log.e("TIME is set", time);
        SharedPreferences preferences = getActivity().getSharedPreferences("TimeDate", 
                                                 Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("Time",time);
        editor.apply();
    }

Ok, that's great. Now we use it on on button listener or Click listener on any view.

//set time
        timeTvLabel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TimePickerFragment pickerDialog = new TimePickerFragment();
          
                pickerDialog.show(getFragmentManager(), "Time Pick");
            }
        });

That's it. We finish our today coding. Hope it's working.

time picker


 Happy coding.

Read More

Android App Settings with Preference Fragment Compat

May 15, 2017

In this post, we will make Android app settings with new Style.
We use PreferenceFragmentCompat.

Why Preference fragment compact? 
Because by using this we can show toolbar on settings activity easily.
Before starting to take a look at documentation click here.

So we need a separate fragment class. Settings is an activity just like others but we implement fragment here.
 Ok, that's our today goal.
Let's start.
Create an Activity name Settings Activity -

public class SettingsActivity extends AppCompatActivity {

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

  if (getSupportActionBar() != null) {
  getSupportActionBar().setDisplayHomeAsUpEnabled(true);
     }

  }

Now set it on Manifest.XML

<activity
  android:name=".settings.SettingActivity"
  android:label="@string/action_settings" />

Note: don't set-


android:parentActivityName=".MainActivity"

if you set this, after pressing the back arrow button on the toolbar it's launch MainActivity again. Now add dependencies to your build.gradle file

compile 'com.android.support:preference-v7:25.3.1'

After that Create a Fragment Class Name SettingFragment.java and extend it to PreferenceFragmentCompat and implements. SharedPreferences.OnSharedPreferenceChangeListener Let me Show-

public class SettingsFragment extends PreferenceFragmentCompat implements
  SharedPreferences.OnSharedPreferenceChangeListener{

  @Override
  public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
  
  }

  @Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

  }

Now add a method on this class name setPreferenceSummery. If we use ListPreference then we set to list selected value. for doing this, add this code-

private void setPreferenceSummery(Preference preference,Object value){

  String stringValue = value.toString();

  if (preference instanceof ListPreference){
  // For list preferences, look up the correct display value in
  // the preference's 'entries' list (since they have separate labels/values).
  ListPreference listPreference = (ListPreference) preference;
  int prefIndex = listPreference.findIndexOfValue(stringValue);
  //same code in one line
  //int prefIndex = ((ListPreference) preference).findIndexOfValue(value);

  //prefIndex must be is equal or garter than zero because
  //array count as 0 to ....
  if (prefIndex >= 0){
  listPreference.setSummary(listPreference.getEntries()[prefIndex]);
  }
  } else {
  // For other preferences, set the summary to the value's simple string representation.
  preference.setSummary(stringValue);
     }
 }

Note: For understanding code, you see comment on the code.

Now time the fulfill the methods onCreatePreferences.
In this methods, we add our XML file for settings option. But we don't create yet. So it's show error status. But don't worry we will add this later. Code-

@Override
  public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
  // Add 'general' preferences, defined in the XML file
  addPreferencesFromResource(R.xml.pref_general);

  SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();

  PreferenceScreen preferenceScreen = getPreferenceScreen();

  int count = preferenceScreen.getPreferenceCount();

  for (int i = 0; i < count ; i++) {
  Preference p = preferenceScreen.getPreference(i);
  if (!(p instanceof CheckBoxPreference)) {
  String value = sharedPreferences.getString(p.getKey(), "");
  setPreferenceSummery(p, value);
       }
     }
  }

Now time to work with onSharedPreferenceChanged-

@Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

  Preference preference = findPreference(key);

  if (preference != null) {

  if (!(preference instanceof CheckBoxPreference)) {
  String value = sharedPreferences.getString(preference.getKey(), "");
  setPreferenceSummery(preference, value);
        }
     }
  }


Optional code: 
if you want to use the content provider to access database then you set a notification for change value-
Activity activity = getActivity();
activity.getContentResolver().notifyChange(CONTENT_URI, null);
After doing that we should register and unregister the shared preference listener with activity life cycle.

Let's do this-
//register and unregister on lifecycle
  @Override
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  getPreferenceScreen().getSharedPreferences()
  .registerOnSharedPreferenceChangeListener(this);
  }

  @Override
  public void onDestroy() {
  super.onDestroy();
  getPreferenceScreen().getSharedPreferences()
  .unregisterOnSharedPreferenceChangeListener(this);
  }


ok. our fragment is ready to use.(don't worry about the error, we will fix this letter, for now just ignore it.)
Now we add the toolbar back arrow code.
so that it's come back the previous activity. For more details use code comment-

@Override
    public boolean onOptionsItemSelected(MenuItem item) {

        /*
         * Normally, calling setDisplayHomeAsUpEnabled(true) 
         * (we do so in onCreate here) as well as
         * declaring the parent activity in the 
         * AndroidManifest is all that is required to get the
         * up button working properly. However, in this case, 
         * we want to navigate to the previous
         * screen the user came from when the up 
         * button was clicked, rather than a single
         * designated Activity in the Manifest.
         *
         * We use the up button's ID (android.R.id.home) 
         * to listen for when the up button is
         * clicked and then call onBackPressed 
         * to navigate to the previous Activity when this happens.
         */

        int id = item.getItemId();

        if (id == android.R.id.home){
            NavUtils.navigateUpFromSameTask(this);
        }

        return super.onOptionsItemSelected(item);
    }

Now in this part, we create XML code.

Are you tired of seeing the error? 
Now time to fix it. we create an XML file name pref_general.xml.
Let's add-
In our settings screen, we just add two preference,

  • List Preference,
  •  Checkbox preference. 

our list preference for text size. so we need to create two arrays on arrays.XML one is for label and others is for value. but we need to add string first (I provide all string for both preferences).

Strings-
<!-- for settings -->
  <!-- ***************START************* -->
  <!-- text size -->
  <string name="sTextSmallLabel">Small</string>
  <string name="sTextMediumLabel">Medium</string>
  <string name="sTextModerateLabel">Moderate</string>
  <string name="sTextLargeLabel">Large</string>
  <string name="sTextExtraLargeLabel">Extra Large</string>

  <!-- text size value-->
  <string name="sTextSmallValue">15</string>
  <string name="sTextMediumValue">17</string>
  <string name="sTextModerateValue">20</string>
  <string name="sTextLargeValue">23</string>
  <string name="sTextExtraLargeValue">26</string>

  <string name="textSizeKey" translatable="false">textSize</string>
  <string name="textSizeLabel">Text Size</string>

  <string name="switchKey">SwitchKey</string>
  <string name="switchLabel">Night Mode</string>
  <string name="switchON">Night Mode ON</string>
  <string name="switchOFF">Night Mode OFF</string>

  <!-- ***************FINISH************* -->

Now add arrays-

<resources>

  <string-array name="textSizeLabel">
  <item>@string/sTextSmallLabel</item>
  <item>@string/sTextMediumLabel</item>
  <item>@string/sTextModerateLabel</item>
  <item>@string/sTextLargeLabel</item>
  <item>@string/sTextExtraLargeLabel</item>
  </string-array>

  <string-array name="textSizeValue">
  <item>@string/sTextSmallValue</item>
  <item>@string/sTextMediumValue</item>
  <item>@string/sTextModerateValue</item>
  <item>@string/sTextLargeValue</item>
  <item>@string/sTextExtraLargeValue</item>
  </string-array>


</resources>

Note my full arrays.xml. Ok, that's enough waiting now add pref_general.xml


<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <ListPreference
  android:defaultValue="@string/sTextModerateValue"
  android:entries="@array/textSizeLabel"
  android:entryValues="@array/textSizeValue"
  android:key="@string/textSizeKey"
  android:title="@string/textSizeLabel"/>

  <CheckBoxPreference
  android:defaultValue="false"
  android:key="@string/switchKey"
  android:summaryOff="@string/switchOFF"
  android:summaryOn="@string/switchON"
  android:title="@string/switchLabel"/>

</PreferenceScreen>

Just one more work to do left to complete Settings-
we need to update activity_settings. we need to set a fragment to on this XML file. Let's add this and this fragment will show our new settings in the settings.

<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/weather_settings_fragment"
    android:name="packageName.settings.SettingFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Ok, that's . we finish our settings.

oh! I just forget to change the theme of styles.XML. Let's add on your main app theme.

<!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
  <!-- must add this line or app will crash -->
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
  </style>

Note: if you don't add this line your app will crash. Be careful. Now you launch this SettingsActivity.java class with intent from your desired class.

See-
settings

It is single preference screen app. But If you want to add multiple screens, follow this post- Android Settings Series

That's all today.
Hope you can use this option for your app.

Happy coding

Read More

Saturday, May 13, 2017

Android Custom Dialog with Material Design

May 13, 2017

Hello, reader.
Welcome to my blog.
How about your day?

In this post, we will make a custom dialog with user input option.

we also use material edit text. Edit text has a floating hint option. we can use it on login option or feedback option. But I am using for feedback option.

So we are going to add a custom dialog so we have to add a layout file.
Our dialog will show exactly what we will design in our layout XML file. In our layout XML file, we have 3 Edit text. Because we need to get three information from our user. Need username and user email address and user feedback.

Add 3 Edit text-

  • Name EditText
  • Email EditText
  • Message EditText


Enough Intro. Let's start.

At first, you need to check that's design dependence is added to your gradle file. But the android studio has already added those dependencies  If not add already then add it. Because you use Text Input layout. I am not showing how to add design dependence, I think you are quite capable of adding this.

Now create a layout File name custom_dialog.xml
We use the Constraint Layout layout as base layout. Now add the Text Input Layout as child layout of the Main layout. After that, We add our EditText as a child layout of TextInputLayout. In the edit text, we add a hint option for Edit text and that's label will float up when user will start writing.

Let's show me the code.
Below code is the full code of our custom dialog XML file.
custom_dialog.xml
<android.support.constraint.ConstraintLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">

  <android.support.design.widget.TextInputLayout
  android:id="@+id/addTaskNameLayout"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_marginEnd="@dimen/card_element_margin"
  android:layout_marginStart="@dimen/card_element_margin"
  android:layout_marginTop="@dimen/card_element_margin"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintTop_toTopOf="parent">

  <EditText
  android:id="@+id/customName"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/custom_name"
  android:inputType="textPersonName"
  android:padding="@dimen/main_list_universal_padding"
  android:textColorHint="?attr/colorAccent"/>
  </android.support.design.widget.TextInputLayout>

  <android.support.design.widget.TextInputLayout
  android:id="@+id/textInputLayout"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_marginEnd="@dimen/card_element_margin"
  android:layout_marginStart="@dimen/card_element_margin"
  android:layout_marginTop="8dp"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintTop_toBottomOf="@+id/addTaskNameLayout">

  <EditText
  android:id="@+id/customEmail"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/custom_email"
  android:inputType="textEmailAddress"
  android:padding="@dimen/main_list_universal_padding"
  android:textColorHint="?attr/colorAccent"/>

  </android.support.design.widget.TextInputLayout>

  <android.support.design.widget.TextInputLayout
  android:id="@+id/addTaskSolLayout"
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_marginEnd="@dimen/card_element_margin"
  android:layout_marginStart="@dimen/card_element_margin"
  android:layout_marginTop="8dp"
  app:layout_constraintHorizontal_bias="0.0"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintTop_toBottomOf="@+id/textInputLayout">

  <EditText
  android:id="@+id/customFeedback"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/custom_feedback"
  android:inputType="textMultiLine"
  android:lines="4"
  android:maxLines="10"
  android:padding="@dimen/main_list_universal_padding"
  android:textColorHint="?attr/colorAccent"/>
  </android.support.design.widget.TextInputLayout>


</android.support.constraint.ConstraintLayout>

Note: I don't add any button on this layout. I use default button in the dialog (positive button or negative button in the dialog) but if need to add your custom design button you can add here.

You are seeing some error. Don't worry about it. it's only for String reference not find in your system. You can override it by yourself. but  I also provide my strings that strings are used for the hint as Edit text.

<!-- Custom dialog layout -->
  <!-- ***************Start************* -->
  <string name="custom_name">Your Name:</string>
  <string name="custom_email">your email:</string>
  <string name="custom_feedback">your message:</string>
  <!-- ***************FINISH************* -->

But after you add all of those strings, you also some error too. It's for dimension reference. I also provide my dimension reference. Let's take a look.

<dimen name="card_element_margin">8dp</dimen>

that's it for XML code.

Now we gonna move on JAVA code.
Let's start where you want to build dialog you can use it on fragment or Activity.
I used in MainActivity, and I created separate methods for this. But it's as like other Alert Dialog but only you should use Layout Inflator to inflate layout.xml. And Edit Text function is as like others. And get the text from edit text also same. we add positive and negative button label as Send and cancel. We get all text in the positive click listener and send it's to Email app through Intent.
Ok, see the code-
private void feedback() {

  AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
  LayoutInflater inflater = this.getLayoutInflater();
  final View dialogView = inflater.inflate(R.layout.custom_dialog, null);
  dialogBuilder.setView(dialogView);

  final EditText name = (EditText) dialogView.findViewById(R.id.customName);
  final EditText email = (EditText) dialogView.findViewById(R.id.customEmail);
  final EditText message = (EditText) dialogView.findViewById(R.id.customFeedback);

  dialogBuilder.setTitle("Send FeedBack");
  dialogBuilder.setMessage("please send me to your feedback.");
  dialogBuilder.setPositiveButton("Send", new DialogInterface.OnClickListener() {
  public void onClick(DialogInterface dialog, int whichButton) {
  String nameStr = name.getText().toString().trim();
  String emailStr = email.getText().toString();
  String messageStr = message.getText().toString().trim();
  
  Intent emailIntent = new Intent(Intent.ACTION_SEND);
  emailIntent.setData(Uri.parse("mailto:"));
  emailIntent.setType("message/rfc822");
  emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"Shudiptotrafder@gmail.com"});
  emailIntent.putExtra(Intent.EXTRA_CC, emailStr);
  emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Life Scheduler Feedback");
  emailIntent.putExtra(Intent.EXTRA_TEXT, nameStr + ":" + messageStr);

  if (emailIntent.resolveActivity(getPackageManager()) != null) {
  startActivity(Intent.createChooser(emailIntent, "Send Email ..."));
  } else {
  Toast.makeText(MainActivity.this, "Sorry you don't have any email app", Toast.LENGTH_SHORT).show();
  }

  }
  });
  dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
  public void onClick(DialogInterface dialog, int whichButton) {
  //pass
  }
  });

  AlertDialog b = dialogBuilder.create();
  b.show();
  }

That's it. Now run your code and use it where ever you want. If you have any queries then you can use comment option.
See the final Screen Short-
custom dialog



Hope this tutorial will help you.
It will help you to implement easily to add feedback option from your app. And if you want to add quick login option in your app, you can use this too, but you need to customize. If you have any quires then you can use the comment section.

Happy coding

Read More