Skip to content

Instantly share code, notes, and snippets.

@vtthach
Created September 4, 2017 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vtthach/abf5c83f64565a7a6340c237b30037f0 to your computer and use it in GitHub Desktop.
Save vtthach/abf5c83f64565a7a6340c237b30037f0 to your computer and use it in GitHub Desktop.
Core leak with dialog fragment
package com.tcsdev.tcsapp.features.usermenu.userprofile;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.InputFilter;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.common.base.Strings;
import com.tcsdev.tcsapp.R;
import com.tcsdev.tcsapp.application.Constants;
import com.tcsdev.tcsapp.application.TcsApplication;
import com.tcsdev.tcsapp.common.activity.ContainerActivity;
import com.tcsdev.tcsapp.common.activity.ToolbarMode;
import com.tcsdev.tcsapp.common.dialog.BottomDialogOption;
import com.tcsdev.tcsapp.common.dialog.UserProfileDialogOption;
import com.tcsdev.tcsapp.common.fragment.BasePresenterFragment;
import com.tcsdev.tcsapp.common.imageloader.ImageLoader;
import com.tcsdev.tcsapp.common.utils.PhotoUtils;
import com.tcsdev.tcsapp.common.utils.UIUtil;
import com.tcsdev.tcsapp.common.widget.edittext.RegexCharacterInputFilter;
import com.tcsdev.tcsapp.common.widget.edittext.phoneformat.UsPhoneNumberFormatter;
import com.tcsdev.tcsapp.features.usermenu.userprofile.injection.DaggerUserProfileComponent;
import com.tcsdev.tcsapp.features.usermenu.userprofile.injection.UserProfileContractor;
import com.tcsdev.tcsapp.features.usermenu.userprofile.injection.UserProfileModule;
import com.tcsdev.tcsapp.features.usermenu.userprofile.model.UserProfileResult;
import com.tcsdev.tcsapp.features.verifyphone.VerifyPhoneFragment;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.OnClick;
import butterknife.OnEditorAction;
import butterknife.OnFocusChange;
import butterknife.OnTextChanged;
import static android.app.Activity.RESULT_OK;
import static com.tcsdev.tcsapp.application.Constants.MAX_LENGTH_PHONE_NUMBER_DISPLAY;
public class UserProfileFragment extends BasePresenterFragment<UserProfileContractor.UserProfilePresenter> implements UserProfileContractor.UserProfileView, BottomDialogOption.OptionCallback {
private static final int MAX_AUTO_FORMAT_LENGHT = 11;
@BindView(R.id.imgAvatar)
ImageView imgAvatar;
@BindView(R.id.labelFullName)
TextView labelFullName;
@BindView(R.id.edFullName)
EditText edFullName;
@BindView(R.id.labelEmail)
TextView labelEmail;
@BindView(R.id.edEmail)
EditText edEmail;
@BindView(R.id.labelPhoneNumber)
TextView labelPhoneNumber;
@BindView(R.id.edPhone)
EditText edPhone;
@BindView(R.id.btnSubmit)
Button btnSubmit;
@BindView(R.id.viewUserProfile)
View viewUserProfile;
@Inject
UserProfileContractor.UserProfilePresenter presenter;
private BottomDialogOption dialogSelectPhoto;
private String photoFilePath;
private Drawable drawableNeedVerify;
private Drawable drawableVerifySuccess;
public static void showMe(Activity activity) {
ContainerActivity.IntentBuilder intentBuilder = new ContainerActivity.IntentBuilder(activity);
Bundle data = new Bundle();
intentBuilder.setFragmentClass(UserProfileFragment.class)
.setData(data)
.setActionTitle(activity.getString(R.string.profile_title))
.setActionMode(ToolbarMode.BACK);
intentBuilder.start();
}
@Override
protected void onInitComponent() {
super.onInitComponent();
DaggerUserProfileComponent.builder()
.appComponent(TcsApplication.getAppComponent())
.userProfileModule(new UserProfileModule(this))
.build()
.inject(this);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initDrawable();
}
private void initDrawable() {
int size = (int) UIUtil.getPixelFromDP(getActivity(), 18);
Rect drawBound = new Rect(0, 0, size, size);
drawableNeedVerify = ContextCompat.getDrawable(getActivity(), R.drawable.ic_verified);
drawableNeedVerify.setBounds(drawBound);
drawableVerifySuccess = ContextCompat.getDrawable(getActivity(), R.drawable.ic_accept);
drawableVerifySuccess.setBounds(drawBound);
}
@Override
protected int getLayoutId() {
return R.layout.user_profile_fragment;
}
@NonNull
@Override
protected UserProfileContractor.UserProfilePresenter getPresenter() {
return presenter;
}
@OnClick(R.id.imgAvatar)
public void onAvatarClicked() {
presenter.onAvatarClicked();
}
@Override
public void onSelectOptionTwo() {
PhotoUtils.startIntentGallery(this, Constants.RequestCode.REQUEST_CODE_PICK_PHOTO, "Pick a photo");
}
@Override
public void onSelectOptionOne() {
photoFilePath = PhotoUtils.startIntentCamera(this, Constants.RequestCode.REQUEST_CODE_CAMERA);
}
@Override
public void onSelectOptionThree() {
presenter.removePhoto();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Constants.RequestCode.REQUEST_VERIFY_PHONE
&& resultCode == RESULT_OK) {
presenter.startGetUserProfile();
} else if (requestCode == Constants.RequestCode.REQUEST_CODE_CAMERA && resultCode == RESULT_OK) {
presenter.onCapturePhotoSuccess(photoFilePath);
} else if (requestCode == Constants.RequestCode.REQUEST_CODE_PICK_PHOTO && resultCode == RESULT_OK && data != null && data.getData() != null) {
presenter.onPickPhotoSuccess(data, getActivity().getApplicationContext());
}
}
@Override
public void updatePhotoWithPath(String photoFilePath) {
ImageLoader.loadImageUrl(imgAvatar,
getAppContext().getApplicationContext(),
photoFilePath, ImageLoader.buildUserProfileRequest());
}
@Override
public void updateUiWithProfileData(boolean isShowVerifyIcon, UserProfileResult result, boolean isNotFacebookUser) {
if (!Strings.isNullOrEmpty(result.photo)) {
ImageLoader.loadImageUrl(imgAvatar,
getAppContext().getApplicationContext(),
result.photo,
ImageLoader.buildUserProfileRequest());
}
edEmail.setText(result.email);
if (isNotFacebookUser) {
edFullName.setNextFocusDownId(R.id.edPhone);
edEmail.setEnabled(false);
} else {
edEmail.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_edit, 0);
edFullName.setNextFocusDownId(R.id.edEmail);
edEmail.setEnabled(true);
}
updatePhoneWithFormat(result.phone);
edFullName.setText(result.name);
updateUiWithPhoneStatus(isShowVerifyIcon, result.isVerifyPhone);
setEnableSubmit(false);
}
private void updatePhoneWithFormat(@NonNull String phone) {
if (phone.length() >= MAX_AUTO_FORMAT_LENGHT) {
String strFirstPart = phone.substring(0, MAX_AUTO_FORMAT_LENGHT - 1);
edPhone.setText(strFirstPart);
String secondPart = phone.substring(MAX_AUTO_FORMAT_LENGHT - 1);
edPhone.append(secondPart);
} else {
edPhone.setText(phone);
}
edPhone.setSelection(edPhone.length());
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initAutoFormatPhoneNumber();
presenter.startGetUserProfile();
}
private void initAutoFormatPhoneNumber() {
edPhone.addTextChangedListener(new UsPhoneNumberFormatter(edPhone));
edPhone.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH_PHONE_NUMBER_DISPLAY), new RegexCharacterInputFilter(Constants.REGEX_PHONE_NUMBER_DISPLAY)});
}
@Override
public void updateUiWithPhoneStatus(boolean isShowIconVerifyStatus, boolean isVerifiedPhone) {
if (!isShowIconVerifyStatus) {
labelPhoneNumber.setCompoundDrawables(null, null, null, null);
} else if (isVerifiedPhone) {
labelPhoneNumber.setCompoundDrawables(null, null, drawableVerifySuccess, null);
} else {
labelPhoneNumber.setCompoundDrawables(null, null, drawableNeedVerify, null);
}
}
@OnTextChanged(value = R.id.edFullName, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
public void onFullNameTextChange(CharSequence charSequence) {
presenter.checkIfFullNameChange(charSequence.toString());
}
@OnTextChanged(value = R.id.edEmail, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
public void onEmailTextChange(CharSequence email) {
presenter.checkIfEmailChange(email.toString());
}
@OnTextChanged(value = R.id.edPhone, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
public void onPhoneNumberTextChange(CharSequence phoneNumber) {
presenter.checkIfPhoneNumberChange(phoneNumber.toString());
}
@Override
public void onResume() {
super.onResume();
resetEditMode();
}
@Override
public void goToVerifyPhone(String phoneNumber, boolean isAutoSendCode) {
VerifyPhoneFragment.showMe(this,
phoneNumber,
Constants.RequestCode.REQUEST_VERIFY_PHONE, isAutoSendCode);
}
@Override
public void setEnableSubmit(boolean isEnable) {
btnSubmit.setEnabled(isEnable);
}
@Override
public void notifyUpdateSuccess(String message) {
showSnackBarMessage(message);
btnSubmit.setEnabled(false);
}
@Override
public void removePhoto() {
imgAvatar.setImageResource(R.drawable.ic_noavatar_big);
}
@Override
public void showDialogSelectPhoto(boolean isRemovePhoto) {
if (dialogSelectPhoto != null) {
dialogSelectPhoto.dismiss();
}
dialogSelectPhoto = UserProfileDialogOption.newInstance(isRemovePhoto);
if (!dialogSelectPhoto.isAdded()) {
// Fixed leak. Note -> do not using getFragmentManager in fragment to show a fragment dialog
dialogSelectPhoto.show(getActivity().getSupportFragmentManager(), BottomDialogOption.TAG);
}
dialogSelectPhoto.setCallback(this);
}
@Override
public void notifyNameRequire() {
edFullName.requestFocus();
edFullName.setError(UIUtil.getSpannableError(getActivity(),
R.string.notify_empty_name));
}
@Override
public void notifyEmailInvalid() {
edEmail.setError(UIUtil.getSpannableError(getActivity(),
R.string.notify_email_not_valid));
edEmail.requestFocus();
}
@Override
public void resetEditMode() {
viewUserProfile.requestFocus();
}
@Override
public void updatePhoneAutoFormat(String phoneWithoutFormat) {
// This is the hack way to work with default PhoneFormat of Android system
edPhone.setText("");
updatePhoneWithFormat(phoneWithoutFormat);
}
@Override
public void notifyPhoneInvalid() {
notifyError(getString(R.string.msg_phone_invalid));
}
@OnClick(R.id.btnSubmit)
public void onSubmitDataButtonClicked() {
presenter.onSubmitButtonClicked(edFullName.getText().toString().trim(),
edEmail.getText().toString().trim(),
edPhone.getText().toString().trim());
}
@OnClick(R.id.labelPhoneNumber)
public void onLabelPhoneNumberClicked() {
presenter.onLabelPhoneNumberClicked(edPhone.getText().toString());
}
@OnEditorAction(R.id.edPhone)
public boolean onDonePhone() {
presenter.needAutoFormatPhone(edPhone.getText().toString());
return false;
}
@OnFocusChange(R.id.edPhone)
public void onFocusChanged(boolean isFocused) {
if (!isFocused) {
presenter.needAutoFormatPhone(edPhone.getText().toString());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment