22nd Chapter Master-detail User interface

Source: Internet
Author: User
Tags hosting

Please refer to the textbook to fully understand and complete the section of this chapter ...

Copy the engineering ch21 and rename the project catalog to ch22.

This chapter will create a user interface that adapts to tablet devices, allowing users to view and interact with lists and detail interfaces at the same time. Figure 22-1 shows a list of such a detail interface. Usually we are also referred to as the master-Slave user interface (Master-detail interface).

Figure 22-1 User interface for displaying lists and details at the same time

The test in this chapter requires a tablet device (I can use a big phone) or AVD. To create a flat avd, start Android Virtual device Manager, and then click Tablet in the Categories category to select a flat AVD device. Finally, the system target version of the AVD was set at API level 17th level. 22-2 is shown below:

Figure 22-2 AVD tablet device selection 22.1 increased layout flexibility

On a mobile device, a CrimeListActivity single-layout (Single-pane) layout is generated. On a tablet, we need it to create a dual-layout (Two-pane) layout to display both master and slave views.

In a two-layout layout, it CrimeListActivity will be both hosted CrimeListFragment and CrimeFragment (22-3).

Figure 22-3 Different types of layouts

To implement a two-layout layout, you need to perform the following steps:

    • Modified SingleFragmentActivity , no longer hard-coded instantiation of the layout;
    • Create a layout that contains two fragment containers;
    • Modified CrimeListActivity to instantiate a single layout on a mobile device, while instantiating a dual layout on a tablet device.
22.1.1 Modify singlefragmentactivity

CrimeListActivityis SingleFragmentActivity the child class. Currently, SingleFragmentActivity only activity_fragment.xml layouts can be instantiated. To make the SingleFragmentActivity class more abstract and flexible, we let its subclasses provide the layout resource ID itself.

In Singlefragmentactivity.java, add a protected method that returns the layout resource ID that the activity requires, as shown in Listing 22-1.

Code Listing 22-1 increased SingleFragmentActivity flexibility of classes (Singlefragmentactivity.java)

Now, although the function of an SingleFragmentActivity abstract class is the same as before, its subclasses can choose to override the getLayoutResId() method to return the desired layout without using a fixed activity_fragment.xml layout. 22.1.2 Create a two Fragment layout of the container

In the package browser, right-click the res/layout/directory, select Create a new layout file, name the file Activity_twopane.xml, and then select LinearLayout as the root element. Refer to Figure 22-4 to complete the XML content definition for the two-layout layout.

Figure 22-4 Layout with two fragment containers (layout/activity_twopane.xml)

Note that the first of the layout definitions FrameLayout also has a fragmentContainer layout resource ID, so SingleFragmentActivity.onCreate(...) the related code for the method can work as before. Once the activity is created, the createFragment() fragment returned by the method will appear in the layout on the left side of the screen.

To test the new layout, CrimeListActivity override the method in the class getLayoutResId() , and return the R.layout.activity_twopane resource ID, as shown in Listing 22-2.

Code Listing 22-2 using a two-layout layout (Crimelistactivity.java)

Run the "Bad Notes" app on a tablet or AVD and make sure you see the user interface shown in 22-5. Note that the details section on the right does not show anything, click on any of the list items, and can not display the corresponding bad habits details. The coding and setup of the crime detail fragment container will be completed later in this chapter.

Figure 22-5 Dual layout on a tablet device

Currently, CrimeListActivity dual-layout user interfaces are generated both on the phone and on the tablet device. The next section will use the alias resource to resolve this issue. 22.1.3 using alias Resources

An alias Resource is a special resource that points to other resources. It is stored in the Res\values\ directory and is defined in the Refs.xml file according to the Convention.

This section creates an alias resource for your phone to point to the Activity_fragment.xml layout, and an alias resource for the tablet to point to the activity_twopane.xml layout.

In the project, right-click the res\values\ directory, create a new XML file, new->values resource file, and name the file Refs.xml, refer to listing 22-3 and add the Item node definition in the new refs.xml.

Code Listing 22-3 Creating the default alias resource value (Res/values/refs.xml)

The alias resource points to a single layout resource file. The alias resource itself also has a resource ID: R.layout.activity_masterdetail . Note that the attribute of the alias type determines what inner class the resource ID belongs to. Even though the alias resource itself resides in the res/values/directory, its resource ID is still attributed to the R.layout inner class.

Modify the CrimeListActivity corresponding code for the class, R.layout.activity_masterdetail replacing it with the resource ID R.layout.activity_fragment , as shown in Listing 22-4.

Code Listing 22-4 Switch layout again (Crimelistactivity.java)

Run the "Bad Habits" app to verify that the alias resource is working correctly. If everything works, you CrimeListActivity should create a single layout again.

Figure 22-5-1 again creates a single layout

Create a dedicated optional resource for a tablet device

The alias resource stored in the values directory is the default alias resource for the system, so the CrimeListActivity default single layout layout is generated.

Now create an optional alias resource to enable the alias resource to point to the Activity_twopane.xml dual layout resource on a large screen device such as a tablet activity_masterdetail .

In the package browser, right-click the Res directory and create a new directory named VALUES-SW600DP. Copy the Res\values\refs.xml file to the RES\VALUES-SW600DP directory, and then refer to listing 22-5, modifying the alias resource to point to the two-layout layout.

Note: If you can't see the new VALUES-SW600DP the catalog, outside the project will be Refs.xml files are copied to RES\VALUES-SW600DP directory.

Code Listing 22-5 Optional Resources for large-screen devices (Res/values-sw600dp/refs.xml)

What does the configuration modifier -sw600dp mean? SWis the smallest width (minimum width) abbreviation, although literally the meaning of width, but it actually refers to the minimum size of the screen (dimension), and thus is SW independent of the device's current orientation.

When determining an optional resource, the -sw600dp configuration modifier indicates that the resource is used for any device with a minimum size of 600DP or higher DP. This is a good practice for specifying the screen size specifications for a tablet.

It should be explained that the minimum width configuration modifier was introduced in Android 3.2. This means that a tablet device running an Android 3.0 or Android 3.1 system does not recognize it.

To work around this issue, you can add an -xlarge optional resource that uses the screen size modifier (available only for previous versions of Android 3.2).

Click the Res directory to create a new directory named Values-xlarge. The Values-sw600dp\refs.xml resource file is then copied to the new Values-xlarge directory. Now we have another resource file as shown in Listing 22-6.

Code Listing 22-6 Optional Resources for Android version 3.2 (Res/values-xlarge/refs.xml)

<resources>

<item name= "Activity_masterdetail" type= "layout" > @layout/activity_twopane</item>

</resources>

The configuration modifier -xlarge contains resources that apply to devices with a minimum size of 720X960DP. This modifier is only available for devices running prior to Android 3.2. Android 3.2 and later system versions will automatically find and use -sw600dp the resources under the modifier directory.

Run the Criminalintent app on your phone and tablet, respectively. Confirm the layout of the single and double layouts to achieve the desired results.

22.2 Custodian of the Activity:fragment

Now that the layout of the single-and-double layouts has been processed, let's start adding CrimeFragment to the crime detail fragment container, allowing CrimeListActivity you to present a full dual-layout user interface.

To maintain the independence of fragment, we can define callback interfaces in fragment and entrust the hosting activity to accomplish tasks that should not be handled by fragment. Managed activity implements the callback interface to perform the tasks of the managed fragment.

Fragment Callback Interface

The usual practice for delegating work tasks to managed activities is that the callback interface named by fragment is defined Callbacks . The callback interface defines the work tasks that fragment delegates to managed activity processing. Any activity that intends to host the target fragment must implement the interfaces for these definitions.

With the callback interface, you don't need to know who your trustee is, fragment can call the managed activity method directly.

Implement CrimeListFragment.Callbacks Callback Interface

To implement an Callbacks interface, first define a member variable to hold Callbacks the object that implements the interface. The managed activity coercion type is then converted to an Callbacks object and assigned to a Callbacks type variable.

In Crimelistfragment.java, add an Callbacks interface. Add another mCallbacks variable and override the onAttach(Activity) onDetach() method, complete the assignment of the variable and empty it, as shown in Listing 22-7.

Code Listing 22-7 Add callback Interface (Crimelistfragment.java)

Now, CrimeListFragment there is a way to invoke the managed activity method. In addition, it does not care who the hosting activity is. As long as the managed activity implements the CrimeListFragment.Callbacks interface, CrimeListFragment All code behavior remains the same.

Note that the CrimeListFragment managed activity is cast to an object without a class security check CrimeListFragment.Callbacks . This means that the managed activity must implement an CrimeListFragment.Callbacks interface. This is not a bad dependency, but it is important to document it.

Next, in the CrimeListActivity class, implement the CrimeListFragment.Callbacks interface, as shown in Listing 22-8. Ignore the onCrimeSelected(Crime) empty method for the time being, we will deal with it later.

Code Listing 22-8 Implementation Callback Interface (Crimelistactivity.java)

Finally, the onListItemClick(...) method is called in the method and when the user creates the new crime CrimeListFragment onCrimeSelected(Crime) . Now, let's start by thinking about how to implement the CrimeListActivity.onCrimeSelected(Crime) method.

onCrimeSelected(Crime)When the method is called, you CrimeListActivity need to complete the following two-select tasks:

    • If using the mobile User interface layout, start the new CrimePagerActivity ;
    • If you use the Tablet user interface layout, it will be CrimeFragment put detailFragmentContainer in.

To determine whether you want to instantiate a phone or a tablet interface layout, you can check the layout ID . But the best and most accurate way to check is to check if the layout is included detailFragmentContainer . Because the layout file name can change at any time, and we don't care which file instantiation the layout is generated from. We just need to know if the layout file contains what you can put CrimeFragment in detailFragmentContainer .

If the proof layout is included detailFragmentContainer , then we will create a fragment transaction and add the crimefragment we need to the detailFragmentContainer . If CrimeFragment it existed before, it should first be detailFragmentContainer removed from the.

In Crimelistactivity.java, the implementation onCrimeSelected(Crime) method, depending on the layout interface, responds to crime the selection, as shown in Listing 22-9.

Code Listing 22-9 Conditional CrimeFragment start (Crimelistactivity.java)

Finally, in the CrimeListFragment class, at the start of the new CrimePagerActivity place, the method is called onCrimeSelected(Crime) .

In Crimelistfragment.java, the modifications onListItemClick(...) and onOptionsItemSelected(MenuItem) methods implement the Callbacks.onCrimeSelected(Crime) invocation of the method, as shown in Listing 22-10.

Code Listing 22-10 Call All callback methods (Crimelistfragment.java)

onOptionsItemSelected(...)when a callback method is called in a method, the crime list is immediately reloaded as soon as a new record is added crime . This is necessary because on a tablet device, the list is crime still visible after new records are added crime . On mobile devices, the crime detail interface appears before the list interface, and the refresh of list items can be handled flexibly.

Run the Criminalintent app on a tablet device. Adding a new crime record, you can see that a CrimeFragment view is immediately added and displayed in the detailFragmentContainer container. Then, try to view the other old records to see CrimeFragment the switch of the view, as shown in 22-6.

Figure 22-6 The associated main interface and detail interface

However, if you modify the crime details, the list items are not refreshed with the latest data. Currently, in the CrimeListFragment.onResume() method, only a new crime record is added, we can immediately re-refresh the display list item interface. However, on a tablet device, CrimeListFragment and CrimeFragment will be visible at the same time. Therefore, when it CrimeFragment occurs, it CrimeListFragment does not pause, and nature never resumes from the paused state. This is the root cause of crime list items that cannot reload the refresh.

Next, we'll add another callback interface in crimefragment to fix the problem.

Implementation of the Crimefragment.callbacks callback interface

CrimeFragmentThe interfaces defined in the class are as follows:

Public interface Callbacks {
void oncrimeupdated (Crime Crime);
}

crimewhen you save a record's modifications, the CrimeFragment class calls the method that hosts the activity onCrimeUpdated(Crime) . The CrimeListActivity class will implement the onCrimeUpdated(Crime) method, thus reloading CrimeListFragment the list.

CrimeFragmentbefore implementing the interface, first CrimeListFragment add a new method to the class to reload the Refresh CrimeListFragment list, as shown in Listing 22-11.

Code Listing 22-11 New UpdateUI () method (Crimelistfragment.java)

Then, in Crimefragment.java, add the callback method interface as well as the mCallbacks member variables and implementations onAttach(...) and onDetach() methods, as shown in Listing 22-12.

Code Listing 22-12 New Crimefragment Callback Interface (Crimefragment.java)

Then implement the interface in the CrimeListActivity class CrimeFragment.Callbacks , onCrimeUpdated(Crime) reloading the list item in the method crime , such as listing 22-13.

Code Listing 22-13 Refresh display crime list (Crimelistactivity.java)

In Crimefragment.java, if the title or problem-handling state of the crime object changes, the calling onCrimeUpdated(Crime) method is triggered, as shown in Listing 22-14.

Code Listing 22-14 Call onCrimeUpdated(Crime) method (Crimefragment.java)

In a onActivityResult(...) method, the Crime date of the object's record, the scene photo, and the suspect are all likely to be modified, so you need to call the method in the method onCrimeUpdated(Crime) . Currently, crime Live photos and suspects do not appear in the list item view, but the side-by CrimeFragment view should show these updates, as shown in Listing 22-15.

Code Listing 22-15 Calling onCrimeUpdated(Crime) method again (Crimefragment.java)

CrimeListActivityNow there is CrimeFragment.Callbacks a good implementation of the interface. However, if you run the Criminalintent app on a mobile device, it will crash. Remember that any managed CrimeFragment activity must implement an CrimeFragment.Callbacks interface. Therefore, we also need to CrimePagerActivity implement the interface in the class CrimeFragment.Callbacks .

For CrimePagerActivity a class, the onCrimeUpdated(Crime) method does nothing, so implement an empty method directly (as shown in Listing 22-16). CrimePagerActivitywhen the class is managed CrimeFragment , a required list load refresh has already been completed in the OnResume() method.

Code Listing 22-16 NULL implementation of the Crimefragment.callbacks interface ( CrimePagerActivity.java )

Run the Criminalintent app on a tablet device. Confirm that CrimeFragment any modifications that occur in the view ListView can be updated, as shown in 22-7.

Figure 22-7 List Refresh shows the modification of the detail interface

So far, the development of the Criminalintent application has all been done.

22nd Chapter Master-detail User interface

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.