How to startActivity() in fragment when activating other activity or fragment? - android

In fragment'A' when a certain condition is established, it should go to 'ChatActivity'.
Intent intent = new Intent(getContext(), ChatActivity.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("uid", matchedUid);
startActivity(intent);
The problem is when other fragment or Activity is showing on the top, the condition is established so startActivity is not executed.. occur an error
'java.lang.String android.content.Context.getPackageName()' on a null object reference
below is entire code
public class MatchFragment extends Fragment implements MatchMVP.View {
private static final String TAG = "MatchFragment";
private MatchPresenter matchPresenter;
private ToggleButton randomMatchBtn;
private ProgressBar progressBar, progressCircle;
private TextView searchingText;
private AdView adView;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v;
setupMVP();
if(matchPresenter.checkOnlineStatus(getContext())) {
v = inflater.inflate(R.layout.fragment_match, container, false);
setupView(v);
matchPresenter.isSearching();
initAd(v);
} else {
v = inflater.inflate(R.layout.fragment_offline, container, false);
}
return v;
}
private void setupMVP() {
matchPresenter = new MatchPresenter(this);
}
private void setupView(View v) {
progressBar = v.findViewById(R.id.progressbar);
progressCircle = v.findViewById(R.id.progressbar_circle);
searchingText = v.findViewById(R.id.searching_text);
progressBar.setVisibility(View.INVISIBLE);
progressCircle.setVisibility(View.INVISIBLE);
searchingText.setVisibility(View.INVISIBLE);
randomMatchBtn = v.findViewById(R.id.random_match_btn);
randomMatchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(matchPresenter.checkOnlineStatus(getContext())) {
if(randomMatchBtn.isChecked()) {
matchPresenter.searchRandomUser();
progressBar.setVisibility(View.VISIBLE);
} else {
matchPresenter.stopMatch();
progressBar.setVisibility(View.VISIBLE);
}
} else {
showSnackBar("error");
}
}
});
}
private void initAd(View v) {
MobileAds.initialize(getActivity(), "ca-app-pub-6263138384822549~5566878684");
adView = v.findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
}
#Override
public void createChatRoom(String matchedUid) {
Intent intent = new Intent(getContext(), ChatActivity.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("uid", matchedUid);
startActivity(intent);
Vibrator vibrator;
if(getContext() != null) {
vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(700);
}
}
#Override
public void showSnackBar(String msg) {
Snackbar snackbar = Snackbar.make(getActivity().findViewById(android.R.id.content), msg, 2500);
View snackBarLayout = snackbar.getView();
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
// Layout must match parent layout type
lp.setMargins(0, 300, 0, 0);
// Margins relative to the parent view.
snackBarLayout.setLayoutParams(lp);
snackbar.show();
}
#Override
public void randomMatchBtnOff() {
randomMatchBtn.setChecked(false);
}
#Override
public void randomMatchBtnDisable() {
randomMatchBtn.setEnabled(false);
}
#Override
public void randomMatchBtnEnable() {
randomMatchBtn.setEnabled(true);
progressBar.setVisibility(View.INVISIBLE);
}
#Override
public void showProgressCircle() {
progressCircle.setVisibility(View.VISIBLE);
searchingText.setVisibility(View.VISIBLE);
}
#Override
public void hideProgressCircle() {
progressCircle.setVisibility(View.INVISIBLE);
searchingText.setVisibility(View.INVISIBLE);
}
#Override
public void goAuthActivity() {
Intent intent = new Intent(getContext(), AuthActivity.class);
intent.putExtra("isSanctioned", true);
startActivity(intent);
assert getActivity() != null;
getActivity().finish();
}
#Override
public void onResume() {
super.onResume();
matchPresenter.checkIsSan();
}
#Override
public void onPause() {
super.onPause();
if(isThreadRunning) {
timeCheckThread.interrupt();
}
}
}
Cause of error is 'Fragment is not attached to its Activity'. Yeah I know. I'm making a randomChatting app with firebase. In this MatchFragment, I'm searching other users. When other users start searching, matched with me then let me know by go to 'ChatActivity'.
But if I'm in other fragment of activity, searching is activating, it can't go ChatActivity. 'Fragment is not attached to its Activity'.
Because I'm in other activity not in this MatchFragment. MatchFragment detached to its Activity.
How go to ChatActivity even if I'm in other activity.

You can either try using requireActivity() instead of getActivity() but since you only need a Context object and not necessarily an Activity object, I suggest you replace getActivity() with requireContext().
If that doesn't work out then you can try following this answer: https://stackoverflow.com/a/30498143
PS: I know this should be shared as a comment but my reputation is currently only 41 and I can't post a comment so writing this as an answer.

Related

Update recycler view in fragment from activity

I have a FloatingActionButton and RecyclerView in one of my fragments. Fab opens a new activity where user can save a task into sqlite and all the saved tasks from sqlite are shown in the recycler view. Now what I want is that when the user saves a new task and click on the back button of the activity from toolbar, the recycler view should be updated automatically. Right now, I have to switch to another fragment and then come back to the previous one to see the newly created task. I researched about it and found that interfaces are the best option for this but I am having problems passing the context of the fragment to the activity.
Here is the activity for new task creation:
public class AddTaskActivity extends AppCompatActivity {
DataUpdateListener dataUpdateListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_task);
dataUpdateListener = (CalendarFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_calendar);
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
supportActionBar.setTitle(R.string.add_task);
supportActionBar.setDisplayHomeAsUpEnabled(true);
}
}
private void saveTask(String task_type, String task) {
// this method is used to save the task in sqlite
byte[] imageByteArray;
if (addPictureBtn.getVisibility() == View.GONE) {
imageByteArray = Utils.getImageByteArray(selectedImage);
if (Utils.saveTask(task_type, imageByteArray, task, 0) != -1) {
AlertDialog alertDialog = Utils.showProgressDialog(this, R.layout.success_popup);
Button okBtn = (Button) alertDialog.findViewById(R.id.okBtn);
okBtn.setOnClickListener(v -> {
alertDialog.dismiss();
finish();
});
}
dataUpdateListener.onDataUpdate();
}
}
public interface DataUpdateListener {
void onDataUpdate();
}
}
This is my fragment which is implementing the interface:
public class CalendarFragment extends Fragment implements AddTaskActivity.DataUpdateListener {
CalendarView calendarView;
TextView noTaskFoundTV;
RecyclerView recyclerView;
FloatingActionButton addTaskBtn;
private FragmentCalendarBinding binding;
CalendarTasksAdapter calendarTasksAdapter;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentCalendarBinding.inflate(inflater, container, false);
return binding.getRoot();
}
#Override
public void onViewCreated(#NonNull #NotNull View view, #Nullable #org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
calendarView = view.findViewById(R.id.calendar);
Calendar calendar = Calendar.getInstance();
long milliTime = calendar.getTimeInMillis();
calendarView.setDate(milliTime, true, true);
recyclerView = view.findViewById(R.id.rv);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(false);
noTaskFoundTV = view.findViewById(R.id.noTaskFound);
addTaskBtn = view.findViewById(R.id.fab);
addTaskBtn.setOnClickListener(v -> {
Intent intent = new Intent(getContext(), AddTaskActivity.class);
startActivity(intent);
});
fetchTodayPendingTasks();
}
public void fetchTodayPendingTasks() {
JSONObject todayTasksFromDB = Utils.getTodayPendingTasksFromDB();
if (todayTasksFromDB != null) {
noTaskFoundTV.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
try {
JSONArray tasks = todayTasksFromDB.getJSONArray("tasks");
calendarTasksAdapter = new CalendarTasksAdapter(getActivity(), tasks);
recyclerView.setAdapter(calendarTasksAdapter);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
#Override
public void onDataUpdate() {
//this toast never triggers/shown when the task is created from the activity
Toast.makeText(getContext(), "Triggered", Toast.LENGTH_SHORT).show();
}
}
For this kind of usage, the best practice is to use Room database which is basically wrapping sqlite with abstraction layer. And then you could use LiveData.
Perfect example with source code can be found here.
Please try to open activity through startActivityResult like
In fragment
Intent intent = new Intent(getContext(), AddTaskActivity.class); startActivityForResult(intent,requestcode);
In addtaskactivity
Intent inten =new Intent()
setResult with OK
and then again check onActivityResult in fragment with request code, you can refresh you view here
Or another way to check and refresh in onStart() method of fragment with one static Boolean variable updated from task activity and again false this Boolean from onstart when you finish refreshing. But first of all I would prefer first way.
You should use onResumed method of fragment lifecycle.
you should override onResumed Method on CalendarFragment
This method is called after returning to the main page.
call fetchTodayPendingTasks(); in onResumed method.
It is better to make changes in the fetchTodayPendingTasks. like this:
public class CalendarFragment extends Fragment implements AddTaskActivity.DataUpdateListener {
CalendarView calendarView;
TextView noTaskFoundTV;
RecyclerView recyclerView;
FloatingActionButton addTaskBtn;
private FragmentCalendarBinding binding;
CalendarTasksAdapter calendarTasksAdapter;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentCalendarBinding.inflate(inflater, container, false);
return binding.getRoot();
}
#Override
public void onViewCreated(#NonNull #NotNull View view, #Nullable #org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
calendarView = view.findViewById(R.id.calendar);
Calendar calendar = Calendar.getInstance();
long milliTime = calendar.getTimeInMillis();
calendarView.setDate(milliTime, true, true);
recyclerView = view.findViewById(R.id.rv);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setHasFixedSize(false);
noTaskFoundTV = view.findViewById(R.id.noTaskFound);
addTaskBtn = view.findViewById(R.id.fab);
addTaskBtn.setOnClickListener(v -> {
Intent intent = new Intent(getContext(), AddTaskActivity.class);
startActivity(intent);
});
calendarTasksAdapter = new CalendarTasksAdapter(getActivity());
recyclerView.setAdapter(calendarTasksAdapter);
fetchTodayPendingTasks();
}
public void fetchTodayPendingTasks() {
JSONObject todayTasksFromDB = Utils.getTodayPendingTasksFromDB();
if (todayTasksFromDB != null) {
noTaskFoundTV.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
try {
JSONArray tasks = todayTasksFromDB.getJSONArray("tasks");
adapter.setData(tasks)
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
#Override
public void onDataUpdate() {
//this toast never triggers/shown when the task is created from the activity
Toast.makeText(getContext(), "Triggered", Toast.LENGTH_SHORT).show();
}
}
and you should define a setData method in your adapter. Do not forget to call notifyDataSetChanged().
public void setData(JSONArray array){
// set to your data list
notifyDataSetChanged();
}

How to make 500 Questions Quiz in android with single activity?

I am creating an android app, where I'll be asking for multiple types of questions using RadioButtons. I don't want to make multiple Activities for these questions. Can anyone please tell me how to do that with a short example, of at least two questions?
You can use multiples fragments... or call the activity itself multiple times...
I did an app like yours and i choose the first method!
This is some fragment of a project that i wrote, and the activity that manipulate it, you will have to change it according to your needs.
Activity
public class CollectActivity extends FragmentActivity {
MyPageAdapter pageAdapter;
NonSwipeableViewPager pager;
SpringIndicator springIndicator;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collect);
List<Fragment> fragments = getFragments();
pager = (NonSwipeableViewPager) findViewById(R.id.view_pager);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
PagerModelManager manager = new PagerModelManager();
manager.addCommonFragment(fragments, getTitles());
ModelPagerAdapter adapter = new ModelPagerAdapter(getSupportFragmentManager(), manager);
pager.setAdapter(adapter);
springIndicator = (SpringIndicator) findViewById(R.id.indicator);
springIndicator.setViewPager(pager);
springIndicator.setOnTabClickListener(new TabClickListener() {
#Override
public boolean onTabClick(int position) {
return false;
}
});
}
private List<Fragment> getFragments() {
List<Fragment> fList = new ArrayList<Fragment>();
fList.add(CollectFragment.newInstance("Fragment 1"));
fList.add(CollectFragment.newInstance("Fragment 2"));
fList.add(CollectFragment.newInstance("Fragment 3"));
//add your fragments with a loop
return fList;
}
private List<String> getTitles() {
return Lists.newArrayList("1", "2", "3");
}
public void swipeFragment() {
pager.setCurrentItem(pager.getCurrentItem() + 1);
}
public int getFragment() {
return pager.getCurrentItem();
}
}
Fragment
public class CollectFragment extends Fragment {
private Button openButton;
private Button confirmationCloseButton;
private Button yesRenew;
private Button noRenew;
private BroadcastReceiver udpMessages;
public static final String EXTRA_MESSAGE = "EXTRA_MESSAGE";
public static final CollectFragment newInstance(String message) {
CollectFragment f = new CollectFragment();
Bundle bdl = new Bundle(1);
bdl.putString(EXTRA_MESSAGE, message);
f.setArguments(bdl);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String message = getArguments().getString(EXTRA_MESSAGE);
View v = null;
if (message.compareTo("Fragment 1") == 0) {
v = inflater.inflate(R.layout.fragment_collect_open, container, false);
openButton = (Button) v.findViewById(R.id.open_button);
openButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i2 = new Intent();
i2.setComponent(new ComponentName("qira.com.locker", "qira.com.locker.Service.MessageService"));
i2.putExtra("Message", "CONFIRM_LOCKER_1_CLOSED");
getContext().startService(i2);
}
});
}
if (message.compareTo("Fragment 2") == 0) {
v = inflater.inflate(R.layout.fragment_collect_close, container, false);
confirmationCloseButton = (Button) v.findViewById(R.id.confirmation_close_button);
confirmationCloseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i2 = new Intent();
i2.setComponent(new ComponentName("qira.com.locker", "qira.com.locker.Service.MessageService"));
i2.putExtra("Message", "OPEN_LOCKER_1");
getContext().startService(i2);
}
});
}
if (message.compareTo("Fragment 3") == 0) {
v = inflater.inflate(R.layout.fragment_collect_renew, container, false);
yesRenew = (Button) v.findViewById(R.id.yes_button);
noRenew = (Button) v.findViewById(R.id.no_button);
yesRenew.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((CollectActivity) getActivity()).swipeFragment();
}
});
noRenew.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(getContext(), ReserveActivity.class);
startActivity(i);
}
});
}
return v;
}
#Override
public void onResume() {
super.onResume();
udpMessages = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() != null && intent.getAction().equals("UDP.MESSAGES.COLLECT")) {
if (intent.getExtras().getString("Type").compareTo("OPEN_LOCKER_1-LOCKER_OPENED") == 0) {
if (((CollectActivity) getActivity()).getFragment() != 0) { // onCreateView called twice, dont know why... workaround to solve this problem
((CollectActivity) getActivity()).swipeFragment();
}
}
if (intent.getExtras().getString("Type").compareTo("CONFIRM_LOCKER_1_CLOSED-TRUE") == 0) {
if (((CollectActivity) getActivity()).getFragment() != 1) { // onCreateView called twice, dont know why... workaround to solve this problem
((CollectActivity) getActivity()).swipeFragment();
}
}
}
}
};
getContext().registerReceiver(udpMessages, new IntentFilter("UDP.MESSAGES.COLLECT"));
}
#Override
public void onPause() {
super.onPause();
getContext().unregisterReceiver(udpMessages);
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
}

Intent - null Pointer Exception

I try to make my own gallery. User can add a rating to every photo.
I want something like this: Main class put all photos on a screen. User click a photo then he can add a rating. Click back button on phone and main class refresh a rating, but intent is always null. Take a look on comments in code.
//My main class.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView)findViewById(R.id.imagegallery);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2);
recyclerView.setLayoutManager(layoutManager);
createLists = prepareData();
adapter = new MyAdapter(getApplicationContext(), createLists);
recyclerView.setAdapter(adapter);
}
//My Adapter class from I send an Intent.
public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
this.context = context;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.photo_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {
viewHolder.title.setText(galleryList.get(i).getImage_title());
stars = (RatingBar) viewHolder.itemView.findViewById(R.id.ratingBar1);
stars.setRating(galleryList.get(i).getStars());
Picasso.with(context)
.load(galleryList.get(i)
.getImage_ID()).centerCrop()
.resize(240, 240)
.onlyScaleDown()
.into(viewHolder.img);
viewHolder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent nextScreen = new Intent(context, ShowPhotoActivity.class);
nextScreen.putExtra("fullPhoto", galleryList.get(i));
nextScreen.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(nextScreen); //everything is OKAY
}
});
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_photo_activity_layout);
fullPhoto = (CreateList) getIntent().getSerializableExtra("fullPhoto"); //IS OKAY
photoID = fullPhoto.getImage_ID();
stars = (RatingBar)findViewById(R.id.ratingBar);
stars.setRating(fullPhoto.getStars());
if(savedInstanceState != null){
stars.setNumStars(savedInstanceState.getInt(starsPoint));
}
mImageView = (ImageView) findViewById(photoID);
mImageView = (ImageView) findViewById(R.id.image1);
mImageView.setImageResource(photoID);
//message = new Intent(getApplicationContext(), MainActivity.class);
stars.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
fullPhoto.set_Stars(rating);
message = new Intent(getApplicationContext(), MainActivity.class);
message.putExtra("Photo", fullPhoto);
message.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
System.out.println(fullPhoto.getStars()); //OKAY
startActivity(message);
}
});
}
//Now we are in main class. ALWAYS null. I've tried every solution on stack
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
CreateList photo = (CreateList) getIntent().getSerializableExtra("Photo"); //NULL
for(CreateList photoTemp : createLists) {
if (photoTemp.getImage_ID() == photo.getImage_ID()) {
photoTemp.set_Stars(photo.getStars());
}
}
}
Use onNewIntent callback provides intent parameter instead of call getIntent() method, so, your code must be like the follow:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
CreateList photo = (CreateList) intent.getSerializableExtra("Photo");
for(CreateList photoTemp : createLists) {
if (photoTemp.getImage_ID() == photo.getImage_ID()) {
photoTemp.set_Stars(photo.getStars());
}
}
}

Why doesn't overridePendingTransition work?

I use this function to create animation when switching between 2 activities. But it makes my app stop (not crash, just like pause). I call overridePendingTransition from Adapter in a Fragment of a Activity.
public class LessonAdapter extends RecyclerView.Adapter {
private List<Lesson> lessonList;
private Context mContext;
public LessonAdapter(Context context, List<Lesson> ll) {
lessonList = ll;
mContext = context;
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.lesson_card,parent, false);
return new LessonHolder(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final LessonHolder lessonHolder = (LessonHolder) holder;
lessonHolder.lessonName.setText(lessonList.get(position).getLessonName());
lessonHolder.lessonName.setTextColor(Color.parseColor("#0B8E46"));
lessonHolder.lessonDescription.setText(lessonList.get(position).getLessonDescription());
lessonHolder.lessonDescription.setTextColor(Color.parseColor("#686868"));
if (lessonList.get(position).getUuid() == 1) {
lessonHolder.lessonCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mContext, WordTypeLessonActivity.class);
mContext.startActivity(i);
((Activity) mContext).overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
}
});
}
if (lessonList.get(position).getUuid() == 2) {
lessonHolder.lessonCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mContext, TenseLessonActivity.class);
mContext.startActivity(i);
((Activity) mContext).overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
}
});
}
if (lessonList.get(position).getUuid() > 2) {
lessonHolder.lessonCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mContext, LessonActivity.class);
i.putExtra("lesson_id", lessonList.get(position).getUuid());
mContext.startActivity(i);
((Activity) mContext).overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
}
});
}
}
#Override
public int getItemCount() {
return lessonList.size();
}
}
You can try calling finish() first.
https://developer.android.com/reference/android/app/Activity.html#overridePendingTransition(int, int)
or supply the desired animation information through a ActivityOptions bundle to startActivity(Intent, Bundle) or a related function
as it recommends in the docs
a stacktrace would be nice and some code from the second activity, also why are you using fragments? Seems like you could do it all in one activity using fragments or not use fragments at all and use two activities.

What causes a fragment to get detached from an Activity?

I have a SignupActivity which will go through several fragments as users go through a signup process. On the last fragment, I'm calling
getActivity().setResult(Activity.RESULT_OK)
since SingupActivity intent was started for result. Some users are crashing at this point, because getActivity() is producing a NPE. I'm not able to figure out what is causing this. Screen rotation is disabled, so there is no reason that I know of for the fragment to detach from the Activity.
Any insight as to what may be causing this, and how I can resolve it?
public class SignupConfirmationFragment extends Fragment {
public static final String TAG = SignupConfirmationFragment.class.getSimpleName();
private User mNewUser;
private myAppClient mmyAppClient;
private Animation rotateAnimation;
private ImageView avatar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNewUser = ((SignUpActivity) getActivity()).getNewUser();
mmyAppClient = ((SignUpActivity) getActivity()).getmyAppClient();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_signup_confirmation, null);
((TextView) v.findViewById(R.id.username_textView)).setText(((SignUpActivity) getActivity()).getNewUser().getName());
avatar = (ImageView) v.findViewById(R.id.avatar);
if (mNewUser.getAvatarImage() != null) {
avatar.setImageBitmap(mNewUser.getAvatarImage());
}
rotateAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.progress_rotate);
v.findViewById(R.id.progress_loading).startAnimation(rotateAnimation);
if (mNewUser.getAvatarImage() != null) {
startAvatarUpload();
} else if (mNewUser.getNewsletter()) {
setNewsletterStatus();
} else {
pauseForOneSecond();
}
return v;
}
private void startAvatarUpload() {
mmyAppClient.uploadUserAvatar(mNewUser.getAvatarImage(), new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
if (mNewUser.getNewsletter()) {
setNewsletterStatus();
} else {
updateFragment();
}
}
},
null,
null);
}
private void setNewsletterStatus() {
mmyAppClient.setNewsletter(mNewUser.getEmail(), mNewUser.getFirstName(), mNewUser.getLastName(), new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
//Log.d(TAG, "Result: " + result);
updateFragment();
}
});
}
private void pauseForOneSecond() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
updateFragment();
}
}, 1000);
}
private void updateFragment() {
rotateAnimation.cancel();
if (isAdded()) {
getActivity().setResult(Activity.RESULT_OK);
AnalyticsManager.logUIEvent("sign up completed");
getActivity().finish();
} else {
AnalyticsManager.logUIEvent("sign up failed");
}
}
}
According to Fragment lifecycle in Android OS, you cannot get the Activity associated with the fragment in the onCreateView, because the Activity with which the Fragment is associated will not be created at that stage.
See the figure below:
Also, refer to this link, http://developer.android.com/guide/components/fragments.html
As you can see the Activity is created in onActivityCreated which is after onCreateView, hence you'll get null if you try to call the Activity in the onCreateView. Try to call it in onActivityCreated or in onStart that should solve your problem.
I hope this helps.

Categories

Resources