Showing posts with label app. Show all posts
Showing posts with label app. Show all posts

Monday, November 14, 2016

Activity's and Fragments

Last summer during my internship I used Fragments quite often and as such for a while I understood at least the basics about Fragments, their use cases, and what strengths and weaknesses come with Fragments. Unfortunately, quite recently I had my knowledge tested on this and I learned quite quickly that I don't understand Fragments as good as I once did. So after going back and using Fragments over the weekend and reading the docs and as many tutorials as possible, I finally at least got a slight refresher on Fragments.


When is it better to use a Fragment over an Activity?


Well, actually they really just work hand in hand. An Activity will hold the context and everything you need for the Fragment, the Fragment however will store information and thus you can pass information easily through from Fragment to Fragment.

When is this useful?


Let's say for a minute that you are a general contractor and have 7 houses you're currently building. For each house you have information you need to know, but shouldn't be included in the list.

Now you could do a list like below where each item in the list is associated with an ID which you send through an intent to another activity. This might look great on phone with a relatively small screen, but on a larger device like a tablet, as you can see below, it could definitely look better.



This is where fragments come to the rescue. Let's go back to that list. Now lets say that each item in that list actually has a reference to a JobSite object that has all of the information about the job site. The fragment can pass objects through the activity to another fragment within the same Activity. Doing that you can fairly easily do something like this.


On a mobile phone you can easily use an animation to slide, expand, fade or whatever animation works best for you. On a tablet however this makes your app more user friendly across a wider range of devices.

How do I pass information to the Activity?


Passing data from the Fragment to the parent Activity is fairly simple. Within the fragment make a call to getActivity() and you can use all of the accessor methods available in the parent Activity.

Thursday, November 10, 2016

Android - Handlers and Data Leaks

This post is mostly for my reference as I use Handlers a lot, but I'm still trying to get use to the idea of a WeakReference. Obviously this isn't rocket science, but up until about 9 months ago I used Handlers in a very improper way (my first example) and undoubtedly ended up with a lot of data leaks in any multi-threaded application I developed.

I am writing this because I recently I was being tested on my Android knowledge, and although I knew about data leaks and how to solve the data leaks, courtesy of Android Studio, I didn't know what was actually causing the data leaks.

If not properly used a Handler will hold a reference to the context of the activity from which it was created which therefore prevents the garbage collector from performing garbage collection on the Activity from which you instantiated the handler. Here's a good example of what NOT to do.
class FooActivity extends Activity {
    private Handler mHandler;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_foo);
        mHandler = createMyHandler();
        createBackgroundThreadWithHandler(mHandler);
    }
    private Handler createMyHandler() {
        return new Handler() {
            @Override handleMessage(Message msg) {
               super.handleMessage(msg);
               Toast.makeText(FooActivity.this, "Hi", Toast.LENGTH_SHORT).show();
            }
        };
    }
}

The above code is not good because we have no idea how long the BackgroundThreadWithHandler will be alive, however as long as it is, it will have a reference to the handler which will have a reference to the context of FooActivity.

So now lets look at the proper way to handle dealing with Handlers. We need to be able to create the handler, however we can't let the handler hold a strong reference to the Context/Activity.

class FooActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_foo);
        createBackgroundThreadWithHandler(new MyHandler(FooActivity.this));
    }    

    void sayHi() {
        Toast.makeText(FooActivity.this, "Hi", Toast.LENGTH_SHORT).show();
    }

    static class MyHandler extends Handler {
        MyHandler(FooActivity fooActivity) {
            weakFooActivity = new WeakReference(fooActivity);
        }   
        @Override handleMessage(Message msg) {
            super.handleMessage(msg);
            FooActivity fooActivity = weakFooActivity.get();
            if (fooActivity != null) {
                fooActivity.sayHi();
            }
        }
    }
}

This example keeps a weak reference to FooActivity which allows the garbage collector to still perform garbage collection on FooActivity.

Friday, October 24, 2014

Android Grow View Dynamically

My problem was I wanted to add animation to my app in order to make it more appealing, and to more along the lines of material design.
I did a couple quick Google searches, but didn't find much. Instead I came up with this quick trick that made it possible.
public class ResizeAnimation extends Animation {
    private int startHeight;
    private int deltaHeight; // distance between start and end height
    private View view;
    /**
    * constructor, do not forget to use the setParams(int, int) method before
    * starting the animation
    * @param v
    */
    public ResizeAnimation (View v) {
        this.view = v;
    }
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        view.getLayoutParams().height = (int) (startHeight + deltaHeight * interpolatedTime);
        view.requestLayout();
     }
    /**
    * set the starting and ending height for the resize animation
    * starting height is usually the views current height, the end height is the height
    * we want to reach after the animation is completed
    * @param start height in pixels
    * @param end height in pixels
    */
    public void setHeightDifference(int start, int end) {
        this.startHeight = start;
        deltaHeight = end - startHeight;
    }
    /**
    * set the starting and ending width for the resize animation
    * starting width is usually the views current width, the end width is the width
    * we want to reach after the animation is completed
    * @param start height in pixels
    * @param end height in pixels
    */
    public void setHeightDifference(int start, int end) {
        this.startWidth = start;
        deltaWidth = end - startWidth;
    }
    /**
    * set the duration for the hideshowanimation
    */
    @Override
    public void setDuration(long durationMillis) {
        super.setDuration(durationMillis);
    }
    @Override
    public boolean willChangeBounds() {
        return true;
    }
}
LinearLayout clickableLayout = (LinearLayout) findViewById(R.id.click able_layout)
clickableLayout.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View V){
        RelativeLayout v = (RelativeLayout) V;
        // getting the layoutparams might differ in your application, it depends on the parent layout
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
        ResizeAnimation a = new ResizeAnimation(relativeLayout);
        a.setDuration(500);
        // set the starting height (the current height) and the new height that the view should have after the animation
        a.setParams(lp.height, newHeight); relativeLayout.startAnimation(a);
        v.startAnimation(a)
    }
}
       
The difference between this and a scale animation is you can actually have one line of text on a linear layout, grow to three lines, but not in a scale like way of squished text. With the XML scale setting you would actually end up having the space all pop up there, but the animation would slowly fill it, with this, it will create the space every time it grows making it more smooth and clean.

Monday, July 14, 2014

MinerMan

https://play.google.com/store/apps/details?id=com.coppercow.minerman

Here's the link to my latest game I've released called MinerMan!

If you enjoy it please tell you're friends and family!

Thursday, February 27, 2014

OK Google!

Yesterday Android developers announced a very long awaited launcher called the Google Now Launcher available at no cost on Google Play. This launcher gives a more current look and feel to a stock Google phone. This launcher also gives accessibility to "OK Google" from the home screen. This means that from the home screen if you say "OK Google" aloud Google will pop up so you can tell it what to do. Google Now launcher made its first appearance on the Nexus 5 device from Google, but did not come stock with Android 4.4 so this is rather a big deal for any Android users who do not want to pay for a Nexus 5, but still want the look, feel, and capabilities(within reason) of the Nexus 5. The new Google Now launcher is available for download here: https://play.google.com/store/apps/details?id=com.google.android.launcher