Categories
discuss

ActionBar Title dynamically change with fragment

I have 1 Activity with 3 Fragments inside (Home-Login-RestorePass) Initially, HomeFragment shows and the other two are hidden. I want that the ActionBar Title change depending on which Fragment is showing.

I’m trying in my Activity with:

public void setActionBarTitle(String title){
    getSupportActionBar().setTitle(title);
}

@Override
public void onResume() {
    super.onResume();
    // Set title
    setActionBarTitle(getString(R.string.app_name));
}

and the fragments has the same:

@Override
public void onResume() {
    super.onResume();
    // Set title
    ((LoginActivity) getActivity()).setActionBarTitle(getString(R.string.fragment_login));
}

But it doesn’t work. It always show R.string.fragment_login on the title.

I’m using FragmentTransaction for the fragment transition:

btnLogin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
            HomeFragment homeFragment = (HomeFragment) getFragmentManager().findFragmentById(R.id.fragmentHome);
            LoginFragment loginFragment = (LoginFragment) getFragmentManager().findFragmentById(R.id.fragmentLogin);
            ft.hide(homeFragment).addToBackStack(null);
            ft.show(loginFragment).addToBackStack(null).commit();
        }
    });

Additionally if i could make appear an Arrow Button (Back) on ActionBar depending of the fragment would be great.

Thanks for your time! Regards.

Answer

Use this method in activity to change the Fragment and set the title programmatically:

private void displayFragment(int position) {
    // update the main content by replacing fragments
    Fragment fragment = null;
    String title = "";
    switch (position) {
    case 0:
        fragment = new Home();
        title = "Home";
        break;
    case 1:
        fragment = new Login();
        title = "Login";
        break;
    case 2:
        fragment = new RestorePass();
        title = "Restore Password";
        break;

    default:
        break;
    }

    // update selected fragment and title
    if (fragment != null) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.frame_container, fragment).commit();
        getSupportActionBar().setTitle(title);
        // change icon to arrow drawable
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_arrow);
    }
}

For example, you want Fragment Home to be displayed:

displayFragment(0);
Categories
discuss

How to create a new RealmObject that contains a RealmList

I need to convert one of my model objects (which was automatically filled from Json using Retrofit) to a Realm Object.

At first, my code was new RealmPoll() instead of realm.createObject(RealmPoll.class). (I was getting NullPointerException just like this question) So I solved that issue. But I cannot find a way to copy a RealmList.

I can’t find any examples of creating RealmObjects with RealmLists in the official Realm website tutorial and the docs say

Only Realm can create managed RealmLists. Managed RealmLists will automatically update the content whenever the underlying Realm is updated, and can only be accessed using the getter of a RealmObject.

which makes me believe it is somehow not possible? But it is a really simple task. I don’t know how to interpret the docs meaning.

Is there any way possible to just convert an object (such as RetrofitPoll below) to a realm object (such as RealmPoll below) if it contains a list?

One function that illustrates my question:

private RealmPoll convertRetrofitPollToRealmPoll(Realm realm, RetrofitPoll retrofitPoll)
{
    RealmPoll realmPoll = realm.createObject(RealmPoll.class);  //<----- fixed, used to be "new RealmPoll()".

    //Convert List<Answer>
    RealmList<RealmAnswer> realmAnswers = new RealmList<RealmAnswer>();  //<----- How to do same thing here?
    for(RetrofitAnswer retrofitAnswer : retrofitPoll.getAnswers())
    {
         realmAnswers.add(convertRetrofitAnswerToRealmAnswer(retrofitAnswer));
    }
    realmPoll.setAnswers(realmAnswers);
}

RetrofitPoll.java

public class RetrofitPoll
{
    private List<Answer> answers;
    private String id;
    private Date startDate;
    private String title;
    private Topic topic;
}

RealmPoll.java

public class Poll extends RealmObject
{
    private RealmList<Answer> answers;
    private String id;
    private Date startDate;
    private String title;
    private Topic topic;
}

Answer

It should be possible to do the following

ObjectWithList obj = new ObjectWithList();
RealmList<Foo> list = new RealmList();
list.add(new Foo());
obj.setList(list);

realm.beginTransaction();
realm.copyToRealm(obj); // This will do a deep copy of everything
realm.commitTransaction();

If you are using Retrofit to create your entire object-graph, you should be able to copy everything into Realm using just one a one-liner. If not, it is a bug.

Note this is also in the docs:

 * Non-managed RealmLists can be created by the user and can contain both managed and non-managed
 * RealmObjects. This is useful when dealing with JSON deserializers like GSON or other
 * frameworks that inject values into a class. Non-managed elements in this list can be added to a
 * Realm using the {@link Realm#copyToRealm(Iterable)} method.

Non-managed lists are created by just doing new RealmList() but this could probably be clearer in the docs.

Categories
discuss

Implement feature like iOS app closing vertical Swipe-to-Dismiss with ViewPager

I currently have Views lined up horizontally in a ViewPager and can cycle through them with a PagerAdapter. Currently, to perform the action that I would like to do on swipe, I have to do a double-tap on the View’s page. I could post code, but it’s somewhat difficult to extract the necessary pieces…

What I would like is the ability to swipe vertically on these views, have them translate vertically with swipe and fade-out, and then perform an action when they reach a certain distance away from the edge of the device.

To get an idea of what I am thinking, in the Gallery app you can pinch an opened photo to zoom-out and open a horizontal filmstrip view. From there you can swipe up (or down) on a photo/video to delete it. For those who do not have the same Gallery app, it’s exactly like closing applications on iOS.

I’ve tried scanning though the source code for the Gallery app, but no luck finding the correct Activity.

Answer

I ended up getting this working more-or-less by cloning the well-written Android-SwipeToDismiss library and just replacing the ListView code with a ViewPager.

The finished product looked like this.

end result

Categories
discuss

Once again getting java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i after updating to Support Tools 23

I had implemented one of the many solutions listed on https://code.google.com/p/android/issues/detail?id=78377 for this issue with 4.2.2 phones but now that I’ve updated to support tools 23 the issue has come back. If you look at that issue report you’ll see there are a lot of people with that same issue since updating. The solutions on NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder also don’t work because they come from https://code.google.com/p/android/issues/detail?id=78377

This is the exception I’m getting:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i
       at android.support.v7.widget.ActionMenuView.getMenu(ActionMenuView.java:643)
       at android.support.v7.widget.Toolbar.ensureMenu(Toolbar.java:876)
       at android.support.v7.widget.Toolbar.getMenu(Toolbar.java:847)
       at android.support.v7.internal.widget.ToolbarWidgetWrapper.getMenu(ToolbarWidgetWrapper.java:702)
       at android.support.v7.internal.app.ToolbarActionBar.getMenu(ToolbarActionBar.java:583)
       at android.support.v7.internal.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:441)
       at android.support.v7.internal.app.ToolbarActionBar$1.run(ToolbarActionBar.java:65)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
       at android.view.Choreographer.doCallbacks(Choreographer.java:579)
       at android.view.Choreographer.doFrame(Choreographer.java:547)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
       at android.os.Handler.handleCallback(Handler.java:800)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:194)
       at android.app.ActivityThread.main(ActivityThread.java:5391)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:525)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
       at dalvik.system.NativeStart.main(NativeStart.java)

My proguard has this:

-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}

Any solutions? getting lots of complaints from users.

Answer

Your ProGuard “keep class” rule needs to be updated, as the targeted classes are no longer being obfuscated. In version 23 of the support tools, Google moved the menu-related classes out of the internal package. I can confirm that the following ProGuard rules eliminated the NoClassDefFoundError that was being seen on certain Samsung devices running Android 4.2.2.

# Workaround for conflict with certain OEM-modified versions of the Android appcompat
# support libs, especially Samsung + Android 4.2.2
# See this thread for more info:
#   https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=78377
-keepattributes **
# Keep all classes except the ones indicated by the patterns preceded by an exclamation mark
-keep class !android.support.v7.view.menu.**,!android.support.design.internal.NavigationMenu,!android.support.design.internal.NavigationMenuPresenter,!android.support.design.internal.NavigationSubMenu,** {*;}
# Skip preverification
-dontpreverify
# Specifies not to optimize the input class files
-dontoptimize
# Specifies not to shrink the input class files
-dontshrink
# Specifies not to warn about unresolved references and other important problems at all
-dontwarn **
# Specifies not to print notes about potential mistakes or omissions in the configuration, such as
# typos in class names or missing options that might be useful
-dontnote **

I strongly recommend that you use dex2jar and jd to confirm that the desired obfuscation has happened (described here: https://stackoverflow.com/a/10191338/315702). Unfortunately, this should be done each time you upgrade the support tools, in case packages are moved or renamed again.

Google moved the classes out of the “internal” package in the hope that this would avoid the classpath conflict that causes the NoClassDefFoundError. However, as Chris Banes stated on the thread for this bug (https://code.google.com/p/android/issues/detail?id=78377), they did not test to verify the fix — and lots of people have since reported the same crash you’re seeing:

Right, we’ve decided to do a one-time rename of the internal classes which should fix this. I have done no testing on those devices though, and don’t plan on doing any either.

Categories
discuss

Classes used to manage exception

Is it good to have a class with short methods used to catch Exceptions?

class ContractUtils{
  public static String getCode(Contract contract) throws MyException{
    try{
      return contract.getInfo().getCode(); //throws ContractException and LogicException
    }catch(Exception e){
      throw new MyException("error during code reading:"+e.getMessage, e);
    }
  }
  //other methods like above...
}

Answer

Your utility class ContractUtil introduces a level of indirection just to translate the original exception into another exception:

Instead of the direct call:

 return contract.getInfo().getCode()

you are now writing the more artificial

 return ContractUtils.getCode(contract);

But there might be situations where this solution can be justified, e.g.:

You are not allowed to throw ContractException or LogicException, and you are calling this method a lot of times.

But if you can change its signature it would e better to redesign the original method to throw only MyException.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..