In Android, we cannot just pass objects to activities. To do this the objects must either implement Serializable or Parcelable interface.
Serializable
Serializable is a standard Java interface. You can just implement Serializable interface and add override methods. The problem with this approach is that reflection is used and it is a slow process. This method creates a lot of temporary objects and causes quite a bit of garbage collection. However, Serializable interface is easier to implement.
Look at the example below (Serializable):
// MyObjects Serializable class
import java.io.Serializable;
import java.util.ArrayList;
import java.util.TreeMap;
import android.os.Parcel;
import android.os.Parcelable;
public class MyObjects implements Serializable {
private String name;
private int age;
public ArrayList<String> address;
public MyObjects(String name, int age, ArrayList<String> address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
public ArrayList<String> getAddress() {
if (!(address == null))
return address;
else
return new ArrayList<String>();
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
// MyObjects instance
MyObjects mObjects = new MyObjects("name", "age", "Address array here");
// Passing MyObjects instance via intent
Intent mIntent = new Intent(FromActivity.this, ToActivity.class);
mIntent.putExtra("UniqueKey", mObjects);
startActivity(mIntent);
Parcelable process is much faster than Serializable. One of the reasons for this is that we are being explicit about the serialization process instead of using reflection to infer it. It also stands to reason that the code has been heavily optimized for this purpose.
Look at the example below (Parcelable):
// MyObjects Parcelable class
import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;
public class MyObjects implements Parcelable {
private int age;
private String name;
private ArrayList<String> address;
public MyObjects(String name, int age, ArrayList<String> address) {
this.name = name;
this.age = age;
this.address = address;
}
public MyObjects(Parcel source) {
age = source.readInt();
name = source.readString();
address = source.createStringArrayList();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
dest.writeStringList(address);
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public ArrayList<String> getAddress() {
if (!(address == null))
return address;
else
return new ArrayList<String>();
}
public static final Creator<MyObjects> CREATOR = new Creator<MyObjects>() {
@Override
public MyObjects[] newArray(int size) {
return new MyObjects[size];
}
@Override
public MyObjects createFromParcel(Parcel source) {
return new MyObjects(source);
}
};
}
Parcelable interface takes more time to implement compared to Serializable interface
Serializable interface is easier to implement
Serializable interface creates a lot of temporary objects and causes quite a bit of garbage collection
Parcelable array can be passed via Intent in android
Use this for Custom Object
public class ResultData implements Parcelable {
public ResultData(Integer id, String name, String tag, String color, List<Criterium> criteria) {
this.id = id;
this.name = name;
this.tag = tag;
this.color = color;
this.criteria = criteria;
}
@NonNull
@PrimaryKey()
@SerializedName(value = "id")
@Expose
private Integer id;
@ColumnInfo(name = "name")
@SerializedName("name")
@Expose
private String name;
@ColumnInfo(name = "tag")
@SerializedName("tag")
@Expose
private String tag;
@ColumnInfo(name = "color")
@SerializedName("color")
@Expose
private String color;
@ColumnInfo(name = "ListData")
@TypeConverters(DataTypeConverter.class)
@SerializedName("criteria")
@Expose
private List<Criterium> criteria = new ArrayList<>();
protected ResultData(Parcel in) {
if (in.readByte() == 0) {
id = null;
} else {
id = in.readInt();
}
name = in.readString();
tag = in.readString();
color = in.readString();
in.readTypedList(criteria, Criterium.CREATOR);
}
public static final Creator<ResultData> CREATOR = new Creator<ResultData>() {
@Override
public ResultData createFromParcel(Parcel in) {
return new ResultData(in);
}
@Override
public ResultData[] newArray(int size) {
return new ResultData[size];
}
};
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public List<Criterium> getCriteria() {
return criteria;
}
public void setCriteria(List<Criterium> criteria) {
this.criteria = criteria;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
if (id == null) {
dest.writeByte((byte) 0);
} else {
dest.writeByte((byte) 1);
dest.writeInt(id);
}
dest.writeString(name);
dest.writeString(tag);
dest.writeString(color);
dest.writeTypedList(criteria);
}
public static Creator<ResultData> getCREATOR() {
return CREATOR;
}
}
Note:- All its Methods and Variable must be Used Parecable
Use this for List<List<String>>
Extending ArrayList and implementing Parcelable on it worked for me.
public class ParcelableArrayList extends ArrayList<String> implements
Parcelable {
private static final long serialVersionUID = -8516873361351845306L;
public ParcelableArrayList(){
super();
}
protected ParcelableArrayList(Parcel in) {
in.readList(this, String.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(this);
}
public static final Parcelable.Creator<ParcelableArrayList> CREATOR =
new Parcelable.Creator<ParcelableArrayList>() {
public ParcelableArrayList createFromParcel(Parcel in) {
return new ParcelableArrayList(in);
}
public ParcelableArrayList[] newArray(int size) {
return new ParcelableArrayList[size];
}
};
}
and Employee class
class Employee implements Parcelable {
List<ParcelableArrayList> details;
//.......
protected Employee(Parcel in) {
details = new ArrayList<ParcelableArrayList>();
in.readTypedList(details,ParcelableArrayList.CREATOR);
//......
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(details);
//.....
}
public int describeContents() {
return 0;
}
public static final Parcelable.Creator<Employee> CREATOR =
new Parcelable.Creator<Employee>() {
public Employee createFromParcel(Parcel in) {
return new Employee(in);
}
public Employee[] newArray(int size) {
return new Employee[size];
}
};
}
Use this for List<List<Object>>.....
Based on comments, I extended the ArrayList class with my custom class and implemented parcelable:
public class TileList extends ArrayList<Tile> implements Parcelable {
public TileList(){
super();
}
protected TileList(Parcel in) {
in.readTypedList(this, Tile.CREATOR);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeTypedList(this);
}
public static final Parcelable.Creator<TileList> CREATOR = new Parcelable.Creator<TileList>() {
public TileList createFromParcel(Parcel in) {
return new TileList(in);
}
public TileList[] newArray(int size) {
return new TileList[size];
}
};
}
and slight changes to my other class:
public class GameBoard implements Parcelable {
private String _id;
public String getId() { return _id; }
public void setId(String id) { _id = id; }
private List<TileList> _tiles;
public List<TileList> getTiles() { return _tiles; }
public void setTiles(List<TileList> tiles) { _tiles = tiles; }
public GameBoard(Parcel in) {
_id = in.readString();
_tiles = new ArrayList<>();
in.readTypedList(_tiles, TileList.CREATOR);
}
public GameBoard() {
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(_id);
parcel.writeTypedList(_tiles);
}
public static final Parcelable.Creator<GameBoard> CREATOR = new Parcelable.Creator<GameBoard>() {
public GameBoard createFromParcel(Parcel in) {
return new GameBoard(in);
}
public GameBoard[] newArray(int size) {
return new GameBoard[size];
}
};
}
That is all. If any help related to this post please comment.
When we have multiple Recycle View in NestedScrollView. Most of the times top views hide behind the toolbar and Recycle View Data comes on top. For resolving these problems use Layout like below ....
You can put this up in a utility class, or if you are defining it within an activity, avoid the activity parameter, or call hideSoftKeyboard(this).
The trickiest part is when to call it. You can write a method that iterates through every View in your activity, and check if it is an instanceof EditText if it does not register a setOnTouchListener to that component and everything will fall in place. In case you are wondering how to do that, it is in fact quite simple. Here is what you do, you write a recursive method like the following, in fact, you can use this to do anything, like setup custom typefaces, etc... Here is the method
public void setupUI(View view) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard(MyActivity.this);
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
That is all, just call this method after you setContentView in your activity. In case you are wondering what parameter you would pass, it is the id of the parent container. Assign an id to your parent container like
and call setupUI(findViewById(R.id.parent)), that is all.
If you want to use this effectively, you may create an extended Activity and put this method in, and make all other activities in your application extend this activity and call its setupUI() in the onCreate() method.
Hope it helps.
If you use more than 1 activity define common id to parent layout like <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>
Then extend a class from Activity and define setupUI(findViewById(R.id.main_parent)) Within its OnResume() and extend this class instead of ``Activity in your program
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 101) {
// The Task returned from this call is always completed, no need to attach
// a listener.
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
}
super.onActivityResult(requestCode, resultCode, data);
}
All process of getting user Data.
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
Log.d("sam",account.getDisplayName()+" "+account.getEmail()+" "+account.getId());
// Signed in successfully, show authenticated UI.
// ..updateUI(account);
} catch (ApiException e) {
// The ApiException status code indicates the detailed failure reason.
// Please refer to the GoogleSignInStatusCodes class reference for more information.
Log.d("sam", "signInResult:failed code=" + e.getStatusCode());
}
}
The Facebook Login SDK for Android is a component of the Facebook SDK for Android. To use the Facebook Login SDK in your project, make it a dependency in Maven, or download it. Choose the method you prefer with the following button.
Go to Android Studio | New Project | Minimum SDK
Select "API 15: Android 4.0.3" or higher and create your new project.
In your project, open your_app | Gradle Scripts | build.gradle
Add the Maven Central Repository to build.gradle before dependencies:
repositories { mavenCentral() }
Add compile 'com.facebook.android:facebook-android-sdk:[4,5)' to your build.gradle dependencies.
Using Maven
In your project, openyour_app>Gradle Scripts>build.gradle (Project)make sure the following repository is listed in thebuildscript { repositories {}}:
In your project, openyour_app>Gradle Scripts>build.gradle (Module: app)and add the following implementation statement to thedependencies{}section to depend on the latest version of the Facebook Login SDK: