Savage F. Morgan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

i started with fragments a few days ago, but it seems wired for me. I dont see the justified advantage for the heavy increase of complexity. I dont know, if i should implement the functionality in my Activity or in my Fragment. First, i tried to put it in the fragments but that often seems to be not possible.

For example: I have a dialog as user input, after button click. So i transfered the button click via listener from fragment to activity and in the activity i opened the dialog. In the dialog I started new functions (so implementation in Activity). Android dev gives the hint to add a alert dialog in a fragment:

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.html

But this fragment still is implemented and heavy coupled with the activty (button action of the dialog is in the activity).

So Model and View are heavy mixed up. I dont see a additional value in such an hard to maintain, static code?!

Whats your opinion and advice about fragments?

###############

Fragments provide the view logic so they are portable to other Activities. For the most part Activities are moving more into the role of a true Controller. In prior Android architectures the view logic and controller logic was mushed together because no one subclassed View to implement most of their app. They essentially did layout in the XML layout files, then pulled out the View objects directly in the Activity. So that meant the Activity was registering click listeners, key listeners, drag logic, etc. which is normally what you'd do in another subclass of View in other toolkits. Because they did this it meant that really cool dragging multi-touch gesture ListView you just coded was stuck in that one Activity. Now you want to use that again in another Activity. Well you're S.O.L. With Fragments you can more easily move that logic from the Activity into a Fragment. Now technically you could move it into a custom component View, but Fragments provide yet another advantage which is Fragments enable you to write applications that can run on tablets and smaller devices all the while varying the layout for each. It's tricky to understand how it works, but a single Activity can contain several Fragments with differing layout for each form factor. Something that a custom component can't accomplish nearly as easily. Plus custom components can't use layout files. You have to go full Java code something you don't have give up with Fragments.

I think the example you provided is a quick and dirty approach to designing Fragments. You could just as easily extract out the back reference (nest scope of this) by extracting an interface that the Fragment delegates to.

##############

When using Fragments, you can think of them as being the View and the Activity as being the Controller. In my personal opinion, Fragments was Google's knee jerk reaction to support tablets, and now we are stuck with them :(

I use fragments everyday, and I certainly feel your pain. When I first read about them I thought to myself, "this is really cool", but after using them, they fall short in so so many ways, but mainly because I would use them incorrectly :(

Here are some of pitfalls that I encountered...

  1. Don't use onclick in your fragment layout, since it's the Activity and NOT the Fragment that will handle the click. If you use the attribute, and later you use the fragment in another Activity, then you'll have to remember to add the onclick method to that Activity as well. So, use a findViewById and then manually attach the click handler in the fragment's onCreateView.

  2. When communicating with other Fragments, use the Activity as the controller to direct the message. (Lots of examples of how do this using interfaces). The key here is that if you are running multiple fragments on a device where one fragment will communicate directly with another fragment, then you run into some odd, but predictable behavior. For example if Fragment A directly updated a View in Fragment B, but Fragment B is not visible (because you've replaced it -- consider a phone), then when Fragment B is visible, then the View may not be updated, since the View is recreated. So, if you update a Fragment be sure to update the data in a fragment then update the View portions in the onCreateView which is called when the fragment becomes visible again (ie, you've popped the current fragment, you are now showing the previous one)

  3. Don't build a complete application using only fragments. Instead build apps like you would normally, using Activities and then treat the Fragment has a glorified view (which it is). ie, design the App such that you have multiple fragments and multiple Activities, and some Activities may use more than 1 fragment.

My first thought with fragments was a one where I thought it would great to just build a complete app using fragments and one activity... I eventually finished the App, but I ran into so many issues using that approach. My next approach was to use multiple fragments and multiple activities and it went much better.

Bottom line is that Fragments are great if you use them as a View, but if you start trying to use them like Activities, then you are going to run into problems :( Think of the Activiy -> Fragment as the being the Controller -> View.

I also recommend that you read and understand the Fragment Lifecycle in addition to the Activity Lifecycle (Pro Android 4 has a great picture to represent it) and you'll save yourself hours of pain :)

#########

Thank you for your advices. according to 1.: I implement the onClickListeners in the Fragment. Sometimes clicks only modifiy the fragment themselves. In addition to that i normally implement a public listener interface in each fragment and implement it in the activity which is using the fragment. With this approach i can transfer the onClicklistener via another listener to the activity At first this sounds overloaded but the benefit is, that i can use the view id, to identificate the button click and only have on listener in my activity which doesnt need to know the ui elements in my fragment. – Fabian Knapp Jun 2 '12 at 12:25
 
Good description and good advice. Somehow I think if Views could use layout files, and if custom components were made easier and encouraged then we wouldn't need Fragments. We could have Activity == Controller, View == View. But somehow that got missed by the Android architects early on. As another best practice Fragments should handle clicks, change events, touch events, etc. Then the Fragment exposes listeners that reads more like business logic: AuthenicateUser, ShareMovie, etc. Then your Activity is divorced from what components you chose to use for display. – chubbsondubs Jun 2 '12 at 23:45
 
##########
Ok, I got it running with mv architecture...
public AlertDialog openLocInput() {

    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
    alert.setTitle("Login");
    alert.setMessage("Enter Pin :");

    // Set an EditText view to get user input
    final EditText input = new EditText(getActivity());
    alert.setView(input);

    alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            jsonHandler.obtainMessage(1, input.getText().toString())
                    .sendToTarget();
            dialog.dismiss();
            return;
        }
    });

    alert.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    return;
                }
            });
    return alert.create();
}

implemented in Fragment... starting this alertdialog from fragment:

 fragment_userlocation_btn_addLocation.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            openLocInput().setOwnerActivity(getActivity());
            openLocInput().show();
        }
    });

also implemented in Fragments.

But I still believe in the overkill theory...

I think <5% of my UI will be reused, so is it recommended to mix up activities loading fragments and activities including the ui logic without fragments?

I think the real advantage of Fragments are tablet optimization, but the usage of tablets compared of usage of mobile devices are very small at this time. In addition to that Tablets are not so "mobile" then mobile devices and are not in focus for context aware development...

##############

That's the thing about reuse. It's hard to predict when you'll use it because you can't predict what future requirements you'll have. Just like a lot of things in life if you ignore it for too long you have a much bigger project on your hands than if you slowly do smaller improvements. Don't cut your grass for 10 years vs. cutting it every 2 weeks. Having some sort of plan means you can do small changes over time to guide your program. – chubbsondubs Jun 2 '12 at 23:48
 
################
reference link: http://stackoverflow.com/questions/10859241/fragments-seems-to-be-overkill-no-mvc-architecture-possible
 
posted on 2013-02-03 16:26  罗斯摩根  阅读(249)  评论(0编辑  收藏  举报