I have two fragments in my activity. When I switch fragment use the code:
private void switchCourseFragment() {
if (mCourseFragment == null || getActivity().isFinishing()) return;
FragmentTransaction mTransaction = mFragmentManager.beginTransaction();
if (mFragmentLogin != null && mFragmentLogin.isAdded()) {
mTransaction.remove(mFragmentLogin);
}
if (!mCourseFragment.isAdded()) {
mTransaction.add(R.id.learncenter_contain, mCourseFragment).commitAllowingStateLoss();
}
}
But this is not what I expected. The mFragmentLogin is not been removed, but the mCourseFragment is been added.
You have to commit for it to take effect.
private void switchCourseFragment() {
if (mCourseFragment == null || getActivity().isFinishing()) return;
if (mFragmentLogin != null && mFragmentLogin.isAdded()) {
mFragmentManager.beginTransaction().remove(mFragmentLogin).commit();
}
if (!mCourseFragment.isAdded()) {
mFragmentManager.beginTransaction().add(R.id.learncenter_contain, mCourseFragment).commitAllowingStateLoss();
}
}
but why don't you use replace instead?
private void switchCourseFragment() {
if (mCourseFragment == null || getActivity().isFinishing()) return;
if (!mCourseFragment.isAdded()) {
mFragmentManager.beginTransaction().replace(R.id.learncenter_contain, mCourseFragment).commitAllowingStateLoss();
}
}
This assume that both your fragments are in the same container.
Related
I'm facing the problem about removing Fragment in SDK < 24.
removeFragment()
FragmentTransaction frgTrans = fragmentMng.beginTransaction();
MyFragment myFrg = (MyFragment) fragmentMng.findFragmentByTag(TAG_MY_FRAGMENT);
frgTrans.remove(myFrg).commit();
getFragment()
MyFragment myFrg = (MyFragment) fragmentMng.findFragmentByTag(TAG_MY_FRAGMENT);
if (myFrg == null ) {
// Do sth
}
// But I checked that myFrg is NOT NULL ???
Furthermore, this problem only happened in SDK < 24 ( Android 5,6 ).
What's difference things between Android SDK < 24 and 24 above ?
I also try to call commitNow() for execute synchronously but it's same problem.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
frgTrans.commit();
fragmentMng.popBackStack();
} else {
frgTrans.commitNow();
}
Anyone here has same problem ?
Update:
I also check Fragment hashcode I get before add and before remove. It's same so I can affirm that it's existing...
05-12 11:34:38.705 3916-3916/myapp.test E/FragmentControllerTest: hashcode before remove: 136290746
05-12 11:34:39.856 3916-3916/myapp.test E/FragmentControllerTest: hashcode before add: 136290746
Update code
Calling follow:
GotoActivity 1: AddMyFragment()
GotoActivity 2: (destroy Activity1 ) removeMyFragment()
BackToActivity1: AddMyFragment() (onResume)
Code:
private void addMyFragment() {
MyFragment myFrg = (MyFragment) mActivity.getSupportFragmentManager().findFragmentByTag(TAG_MY_FRAGMENT);
if (myFrg == null) {
try {
myFrg = new MyFragment();
FragmentTransaction frgTrans = mActivity.getSupportFragmentManager().beginTransaction();
frgTrans.add(R.id.my_fragment, myFrg, TAG_MY_FRAGMENT);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
frgTrans.commit();
} else {
frgTrans.commitNow();
}
} catch (Exception e) {}
} else {
Log.e(TAG, "hash code after remove: " + myFrg.hashCode());
}
}
private void removeMyFragment() {
MyFragment myFrg = (MyFragment) mActivity.getSupportFragmentManager().findFragmentByTag(TAG_MY_FRAGMENT);
if (myFrg != null) {
Log.e(TAG, "hash code after add: " + myFrg.hashCode());
try {
FragmentTransaction frgTrans = mActivity.getSupportFragmentManager().beginTransaction();
frgTrans.remove(myFrg);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
frgTrans.commit();
mActivity.getSupportFragmentManager().popBackStack();
} else {
frgTrans.commitNow();
}
} catch (Exception e) {}
}
}
if (buttonClicked.contains(1) && buttonClicked.contains(2)) {
if (playerOneLastClicked) {
imgViewBackground1.setImageResource(R.drawable.rca)
} else {
imgViewBackground1.setImageResource(R.drawable.wac)
}
}
if (buttonClicked.contains(3) && buttonClicked.contains(4) && buttonClicked.contains(5)) {
if (playerOneLastClicked) {
imgViewBackground2.setImageResource(R.drawable.rca)
} else {
imgViewBackground4.setImageResource(R.drawable.wac)
}
}
when player1 or player2 last click in (buttonClicked.contains(1) && buttonClicked.contains(2)) imgViewBackgound1 change but when the players click button 3,4 or 5 imgViewBackground keep changing.
I want when imgViewBackground1 take (R.drawable.rca) or (R.drawable.wac) don't change any more.
If imgViewBackground is not going to have an imageview you could just add an extra check e.g.
if (imgViewBackground1.drawable == null) {
if (playerOneLastClicked) {
imgViewBackground1.setImageResource(R.drawable.rca)
} else {
imgViewBackground1.setImageResource(R.drawable.wac)
}
}
}
or if it would have an imageview already and you don't want it set again
if (imgViewBackground1.drawable != resources.getDrawable(R.drawable.rcs, null)
|| imgViewBackground1.drawable != resources.getDrawable(R.drawable.wac, null))
if (playerOneLastClicked) {
imgViewBackground1.setImageResource(R.drawable.rca)
} else {
imgViewBackground1.setImageResource(R.drawable.wac)
}
}
}
I am calling one webservice in home page in that i will send all the details in that this process is working in bacground. when i come to this home page again i want to know prvious AsyncTask is end or not
what iam doing exactly here
public void callAsynchronousTask() {
//http://stackoverflow.com/questions/6531950/how-to-execute-async-task-repeatedly-after-fixed-time-intervals
final Handler handler = new Handler();
Timer timer = new Timer();
doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
if (vist != null && saves != null && prof != null && semail != null) {
if (vist.getStatus() != AsyncTask.Status.RUNNING) {
if (saves.getStatus() == AsyncTask.Status.PENDING || saves.getStatus() == AsyncTask.Status.FINISHED && saves.getStatus() != AsyncTask.Status.RUNNING)
{
if (prof.getStatus() == AsyncTask.Status.PENDING || prof.getStatus() == AsyncTask.Status.FINISHED && prof.getStatus() != AsyncTask.Status.RUNNING)
{
if (semail.getStatus() == AsyncTask.Status.PENDING || semail.getStatus() == AsyncTask.Status.FINISHED && semail.getStatus() != AsyncTask.Status.RUNNING)
{
checkandsave();
}
}
}
}
} else {
checkandsave();
}
public void checkandsave(){
ConnectionDetector cd = new ConnectionDetector(Home_page.this);
Boolean isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent) {
DatabaseToadd da = new DatabaseToadd(Home_page.this);
mu = new ArrayList<>();
mu = da.getAllUser();
if (mu.size() > 0) {
vist = new Getvisiterid();
saves=new SaveVisitor();
semail=new sendemail();
prof=new saveprofpic();
vist.executeOnExecutor(THREAD_POOL_EXECUTOR);
}
}
else {
System.out.println("null db");
}
but in this when i come back to this actvity if asynctask running in background then also its showing null if i create object on top its showing pending
Based on your text I'm making the assumption you only need this task run in this activity, and dont need multiple tasks run at once. If this is the case use an asynctaskloader. The asynctask is tied to the lifecycle of the activity and you receive callbacks when it is starting, running in background, and done.
AsyncTaskLoader basic example. (Android)
What is the difference between them? As far as I can see they both do the same thing.
If you go to sources, you will find PhoneWindow.class that have implementation of Window.setBackgroundDrawable method:
#Override
public final void setBackgroundDrawable(Drawable drawable) {
if (drawable != mBackgroundDrawable || mBackgroundResource != 0) {
mBackgroundResource = 0;
mBackgroundDrawable = drawable;
if (mDecor != null) {
mDecor.setWindowBackground(drawable);
}
if (mBackgroundFallbackResource != 0) {
mDecor.setBackgroundFallback(drawable != null ? 0 : mBackgroundFallbackResource);
}
}
}
As you can see, it calls different method of DecorView setWindowBackground:
public void setWindowBackground(Drawable drawable) {
if (getBackground() != drawable) {
setBackgroundDrawable(drawable);
if (drawable != null) {
drawable.getPadding(mBackgroundPadding);
} else {
mBackgroundPadding.setEmpty();
}
drawableChanged();
}
}
Which is actually use method DecorView.setBackgroundDrawable but also provides additional logic for Window. So I would suggest you to use getWindow().setBackgroundDrawable().
I need a little help to get an idea of how to refactor my code, but I can't see options besides what's done, I would like to add the objects but not using so many lists (and if's conditions).
Here is my code, if anyone could help, I appreciate. Thanks
#ViewById
BannerHomeViewPager place1, place2, place3, place4, place5, place6, place7,
place8, place9;
The lists:
private List<HomeItem> allHomeItems = new ArrayList<HomeItem>(),
placeItems1 = new ArrayList<HomeItem>(),
placeItems2 = new ArrayList<HomeItem>(),
placeItems3 = new ArrayList<HomeItem>(),
placeItems4 = new ArrayList<HomeItem>(),
placeItems5 = new ArrayList<HomeItem>(),
placeItems6 = new ArrayList<HomeItem>(),
placeItems7 = new ArrayList<HomeItem>(),
placeItems8 = new ArrayList<HomeItem>(),
placeItems9 = new ArrayList<HomeItem>();
1) Items mocked, ok.
2)
#UiThread
void updateUI() {
if (allHomeItems != null && allHomeItems.size() > 0) {
for (HomeItem item : allHomeItems) {
if (item.getPlacement().contains("1")) {
placeItems1.add(item);
} else if (item.getPlacement().contains("2")) {
placeItems2.add(item);
} else if (item.getPlacement().contains("3")) {
placeItems3.add(item);
} else if (item.getPlacement().contains("4")) {
placeItems4.add(item);
} else if (item.getPlacement().contains("5")) {
placeItems5.add(item);
} else if (item.getPlacement().contains("6")) {
placeItems6.add(item);
} else if (item.getPlacement().contains("7")) {
placeItems7.add(item);
} else if (item.getPlacement().contains("8")) {
placeItems8.add(item);
} else {
placeItems9.add(item);
}
}
}
setupAdapters();
}
3) setupAdapters()
private void setupAdapters() {
if (place1 != null)
place1.update(placeItems1);
if (place2 != null)
place2.update(placeItems2);
if (place3 != null)
place3.update(placeItems3);
if (place4 != null)
place4.update(placeItems4);
if (place5 != null)
place5.update(placeItems5);
if (place6 != null)
place6.update(placeItems6);
if (place7 != null)
place7.update(placeItems7);
if (place8 != null)
place8.update(placeItems8);
if (place9 != null)
place9.update(placeItems9);
}
As #DanielBo answer:
private Map<String, ArrayList<HomeItem>> placeItems = new HashMap<String,ArrayList<HomeItem>>();
void updateUI() {
if (allHomeItems != null && allHomeItems.size() > 0) {
for (HomeItem item : allHomeItems) {
if(!placeItems.containsKey(item.getPlacement())){
placeItems.put(item.getPlacement(), new ArrayList<HomeItem>());
}
placeItems.get(item.getPlacement()).add(item);
}
}
setupAdapters();
}
But why are you using so many views? I really can't say if this is correct bcs i don't know the purpose of this, but I can't figure a good use to so many list views in the same layout...