From scratch - the system in-depth study android (practice - let's start writing code - Beginner's Guide -6 use Fragments build dynamic UI) ...

 

Chapter 6 Using Fragments build dynamic UI

To create a dynamic user interface in a multi-plane Android, you need to conduct encapsulation UI components and activity to act a way interchangeable modules. We can use the Fragment class to create these modules, which acts a bit like a nested act, it can define your own layout and manage their life cycle. Fragment has more obvious advantages, it is Android3.0 new API. When a fragment designated its layout, which can be configured to act in different combinations to modify your layout configured for different screen size, a screen may show only a small fragment, and may be displayed in the large screen in two or 2 one or more of the fragment. This chapter explains how to use the fragment to create a dynamic user experience and optimize the user experience for different screen sizes of equipment, while continuing to support Android1.6 such as this old version. The following is the content preview:

1. Use Android support library

By binding Android support library, learn how to use a recent version of the new APIs

2. Create a Fragment

Learn how to create and implement some basic behaviors fragment

3. Build a flexible UI

Learn how to provide different for different screen fragment layout configuration

4. Fragment communicate with other

Learn how to set up a communication path to communicate with the start fragment to fragment or Activity

6.1 Android support library

Android Support Library (Support Library) provides a support API library Jar files, the library allows you to use the recent system version of the API in an early version of the system, the good news is that Support Library provides a Fragment version of the APIs, so we the system can be between 1.6 to 3.0 version can also use it. This section briefly describes how to set Support Library to support a low fragments so that our system version of the application supports dynamic night UI.

6.1.1 set up according to our engineering support library

1. Download Android Support SDK Manager package, shown in Figure 6-1:

 

Figure 6-1 Download Android Support screenshot

2. Create a libs directory in your Android project

3. Locate your jar file, copy that you want to use the library to ligs / directory, for example,

<sdk>/extras/android/support/v4/android-support-v4.jar

4. Update your manifest file sets the minimum API Level 4, the target API Level 15 (as of the moment the latest system version 4.0.3)

<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" />

 

6.1.2 Import We support library APIs

Support Library contains various APIs, you might want to use these APIs, in order to consider the use of low version of the system users, they may not have this system APIs. SL is designed for it for us. You can find all the documentation about the API SL, please refer to android.support.v4 official API documentation. *

When you use the SL, especially if you pay attention to your own development environment using the new system, and the use of new Fragment class, you should be careful compatibility, not all related to equipment like you are using a new system, you should introducing shown in Listing 6-1:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
...

 

Listing 6-1

6.2 Creating a Fragment

You can think of a Fragment as a part of the act modular, it has its own life cycle, receives its own input event, the act is running, you can add or delete. This section explains how to use the Fragment class library support in the case, our application is still running on the old system version Android 1.6. Of course, if you declare your application directly support a minimum API level is 11 (android 3.0), then it is not necessary to use support libraries, but this approach is not desirable at present.

6.2.1 Creating a Fragment class

First, we need to inherit Fragment class, then override key life-cycle approach, just as Activity. In fact the way we need to rewrite only onCreateView () this method, because of the need to create a layout here, Fragment to run correctly, we can refer to the following code in Listing 6-2:

Copy the code
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
 
public class ArticleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) {
        // 为这个fragment填充布局
        return inflater.inflate(R.layout.article_view, container, false);
    }
}
Copy the code

 

Listing 6-2

Like activity, a fragment should also implement other lifecycle callback methods to allow you to manage the state (such as adding or deleting from the activity), for example, when the act calls onPause (), any fragments in the act of will receiving the onPause () callback. More details about the fragment to use, will explain the API framework.

6.2.2 Use XML to add a Fragment Activit the y- in

fragments are reusable modular UI components, each instance of the class must FragmentActivity Fragment associated parent object. You can in activity in the layout XML file to define each fragment to complete the association. Note that if you created the minimum supported version of the API Level 11 system then you can use Activity directly, because FragmentActivity is designed for earlier versions of the system, and supports library Fragment. Here is an example of a layout file, when the screen of your device as "large", allows you to add two fragments in one act in. As shown in Listing 6-3:

res/layout-large/news_articles.xml:

Copy the code
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
 
    <fragment android:name="com.example.android.fragments.HeadlinesFragment"
              android:id="@+id/headlines_fragment"
              android:layout_weight="1"
              android:layout_width="0dp"
              android:layout_height="match_parent" />
 
    <fragment android:name="com.example.android.fragments.ArticleFragment"
              android:id="@+id/article_fragment"
              android:layout_weight="2"
              android:layout_width="0dp"
              android:layout_height="match_parent" />
 
</LinearLayout>
Copy the code

 

Listing 6-3

Here's how to use the above layout xml file in the code, as shown in Listing 6-4:

Copy the code
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
 
public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.news_articles);
    }
}
Copy the code

 

Listing 6-4

Note: When you define fargment by xml, at run time can not be removed. The next section we'll explain how to dynamically interact with the user 

6.3 to create a flexible Fragment

When you order to support a wide range of screen sizes and design your App, you can reuse your fragments in different layout configurations to optimize the user experience various screen sizes. For example, a fragment of a time display on the phone, on the contrary due to the larger screen may appear in more fragment plates.

Let's take a look at Figure 6-2:

 

Figure 6-2 Use of different Fragment at the plate and on the phone

FragmentManager class provides add, delete, replace method fragment using can run Activity time to create a dynamic user experience.

6.3.1 Adding a Fragment running in Activity

Instead of using xml defined fragments, not as dynamically add more flexibility at run time. If you plan to change fragments act in the life cycle, use a dynamic mechanism is necessary. Such as adding or removing implementation of a fragment of the transaction, we have to use FragmentManager class to create a FragmentTransction, which provides add, remove, replace a variety of APIs fragment. If you act allows the fragments to be removed and replaced, then you should add the initial (also understood as the original parent class) fragment to onCreate () of the act. A very important rule is that when dealing with fragments, particularly those that add runtime fragment, there must be a View container package fragment. We still use on a layout xml file, but show only a fragment, because we support a layout rather than the layout-large, because we use the code to dynamically add fragments, so the XML fragment node can not have declared. And XML is only one FrameLayout, as shown in Listing 6-5:

res/layout/news_articles.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

 

Listing 6-5

 

In our activity, a support library APIs calls getSupportFragmentManager () to get a FragmentManger. Then call beginTransaction () to create a FragmentTransaction through its add () method to add a fragment. You can use the same FragmentTransaction fragment to perform multiple processing transactions in the act. When you are determined to change, you need to call commit () to commit our operations. Specific operations, as shown in Listing 6-6:

Copy the code
Import android.os.Bundle;
 Import android.support.v4.app.FragmentActivity; 
 
public  class the MainActivity the extends FragmentActivity { 
    @Override 
    public  void the onCreate (the Bundle savedInstanceState) {
         Super .onCreate (savedInstanceState); 
        the setContentView (R.layout.news_articles); 
 
        // check whether the air FrameLayout 
        IF (findViewById (R.id.fragment_container)! = null ) {
             // If we are to recover from the previous state, then we do not need to do anything directly back 
            IF (savedInstanceState! = null ) {
                 return  ;
            }
 
             // Create a HeadlinesFragment objects, the optical disc with such resources to achieve 
            HeadlinesFragment firstFragment = new new HeadlinesFragment ();
             // to set a fragment Intent's extras parameters 
            firstFragment.setArguments (its getIntent () getExtras ().); 
            
            // add fragment to 'the fragment_container' (the FrameLayout) 
            getSupportFragmentManager () beginTransaction (). 
                    .add (R.id.fragment_container, firstFragment) .commit (); 
        } 
    } 
}
Copy the code

 

Listing 6-6

Because the fragment is added at runtime to FrameLayout, rather than the 6.2 we use layout XML file is written to the fragment <fragment> in, so we can dynamically add, remove, replace fragment.

6.3.2 Replace Fragment

替换fragment ,不是用add()而是使用replace()。请记住,当你使用FragmentTransaction执行更换或删除一个fragment交易,它常 常是适当允许用户向后导航“撤消”的转变。在你提交之前请调用FragmentTransaction.addToBackStack()方法。当删除或 替换一个fragment,并添加回栈的操作时,被删除的fragment已停止(没有被destroyed)。如果用户后退导航,那么fragment 恢复并重新启动。如果你不添加addToBackStack(),则当fragment被移除和替换时,直接被destroyed。下面我们看下代码清单 6-7:

Copy the code
// 创建fragment并给他一个参数用于确定选择文章的位置
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
 
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 
//我们需要把文章标题Fragment替换为文章内容Fragment
// 我们添加了addToBackStack(),表示用户向后导航的时候fragment不会被destroyed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
 
// 提交
transaction.commit();
Copy the code

 

代码清单6-7

如果在addToBackStack()中传入null,表示你可能更高级的操作,例如使用FragmentManager.BackStackEntry。

6.4 与其他Fragment通信

为了重用Fragment的UI组件,你应该建立一个定义了自己的布局和行为的完全独立并模块化的组件。一旦你定义了这些可重用的 Fragment,你可以与Activity相关联,并与应用逻辑连接,以实现整体复合UI。通常情况下,你会想几个Fragment相互通信,例如基于 用户事件改变内容。所有Fragment的通信是通过相关的Activity。两个Fragment,不应该直接通信。

6.4.1定义一个接口

为了允许一个Fragment 与Activity通信, 你可以在Fragment类里定义一个接口并在Activity中实现此接口。Fragment在它的onAttach()生命周期方法中捕获接口的实 现,然后调用接口方法为了与Activity通信。下面让我们来看下代码清单6-8:

Copy the code
public class HeadlinesFragment extends ListFragment {
    OnHeadlineSelectedListener mCallback;
 
    // 容器Activity必须实现这个接口,用来传递消息
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }
 
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        
        // 确保容器Activity已经实现回调接口,如果没有则会抛出一个异常
        try {
            mCallback = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }
    
    ...
}
Copy the code

 

代码清单6-8

现在fragment能通过调用Activity中的onArticleSelected() 方法来传递消息了。等会我们将展示实现的代码。

例如下面的onListItemClick()方法,当用户点击fragment 中的list item时会调用此方法。我们这个fragment 使用这个回调接口传递事件到父类Activity。如代码清单6-9所示:

 
  @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        //通知父类activity选择的item
        mCallback.onArticleSelected(position);
    }

 

代码清单6-9

6.4.2 实现一个接口

为了从fragment接收事件回调, 父类activity必须实现这个在fragment类中定义的接口。例如下面的代码实现了这个接口,如代码清单6-10所示:

Copy the code
public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...
    
    public void onArticleSelected(Uri articleUri) {
        //用户从HeadlinesFragment选择文章的标题
        // do something
    }
}
Copy the code

 

代码清单6-10

6.4.3 传递消息到Fragment

我们通过Fragment实例的findFragmentById()方法直接获取ArticleFragment。

关于接口的具体实现,下面让我们看下代码清单6-11:

Copy the code
public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...
 
    public void onArticleSelected(int position) {
        //用户从HeadlinesFragment选择文章的标题
        //从 res/layout-large/获得文章 fragment
        ArticleFragment articleFrag = (ArticleFragment)
                getSupportFragmentManager().findFragmentById(R.id.article_fragment);
 
        if (articleFrag != null) {
            //如果articleFrag不为空,我们正在使用的是双面板布局(平板设备)
            //调用 ArticleFragment的这个方法来更新内容
            articleFrag.updateArticleView(position);
        } else {
            //否则,我们使用的是单面板(手机设备)
 
            //创建fragment并给他传入一个参数用于确定选择文章的位置
            ArticleFragment newFragment = new ArticleFragment();
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newFragment.setArguments(args);
        
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 
            //我们需要把文章标题Fragment替换为文章内容Fragment
            //表示用户可以后退导航
            transaction.replace (R.id.fragment_container, newFragment); 
            transaction.addToBackStack ( null ); 
 
            // Finally submitted transaction using 
            transaction.commit (); 
        } 
    } 
}
Copy the code

 

Listing 6-11

Reproduced in: https: //www.cnblogs.com/Codenewbie/articles/2973165.html

Guess you like

Origin blog.csdn.net/weixin_34128411/article/details/93448185