从本章开始我们要做一个CriminalIntent应用。为了界面的灵活性,需要使用fragment

Starting CriminalIntent

Adding dependencies in Android Studio

app/build.gradle中添加依赖项。注意,项目有两个build.gradle文件, 一个是针对整个项目的,一个是针对app module。我们要更改的是后一个。

直接添加依赖项容易出错, 但可以通过File - Project Structure - Modules - app - Dependencies向导添加。 我们需要添加的是Library Dependency中的support-v4
添加完成后你会在app/build.gradle文件中看到类似语句

dependencies{
  compile fileTree(include: ['*.jar'], dir: 'libs')
  compile 'com.android.support:support-v4:25.0.1'
}

Creating the Crime class

public class Crime{
  private UUID mId;
  private String mTitle;

  public Crime(){
    mId = UUID.randomUUID();
  }
}

Hosting a UI Fragment

为了管理UI fragmentactivity必须:

  • layout为其定义一个展示的spot
  • 管理fragment的生命周期

The fragment lifecycle

fragment lifecycle

Two approaches to hosting

  • add the fragment to the activity’s layout
  • add the fragment in the activity’s layout

第一种方式简单但缺乏灵活性,第二种方式更复杂当可以随时更改界面样式

Defining a container view

activity_crime.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"/>

Creating a UI Fragment

Defining CrimeFragment’s layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  >
  <EditText android:id="@+id/crime_title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/crime_title_hint"
    />
</LinearLayout>

Creating the CrimeFragment class

新建CrimeFragment.java

import android.support.v4.app.Fragment;
public class CrimeFragment extends Fragment {
}

注意Fragment有两个库可以引用,android.appandroid.support.v4.app,请选择后者

Implementing fragment lifecycle methods

实现onCreate()函数

public class CrimeFragment extends Fragment {
    private Crime mCrime;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mCrime = new Crime();
    }
}

注意和activity不同的是fragment的所有生命周期函数都是public, 且并不是在onCreate()绑定layout文件,而是需要通过onCreateView()函数实现

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_crime, container, false);
    return v;
}

Wiring widgets in a fragment

onCreateView()函数中绑定widget

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_crime, container, false);
    mTitleField = (EditText)v.findViewById(R.id.crime_title);
    mTitleField.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(
            CharSequence s, int start, int count, int after) {
            // This space intentionally left blank
        }
        @Override
        public void onTextChanged(
            CharSequence s, int start, int before, int count) {
            mCrime.setTitle(s.toString());
        }
        @Override
        public void afterTextChanged(Editable s) {
            // This one too
        }
    });

    return v;
}

Adding a UI Fragment to the FragmentManager

我们使用FragmentManager来操作管理fragment

public class CrimeActivity extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crime);
        FragmentManager fm = getSupportFragmentManager();
    }
}

Fragment transactions

public class CrimeActivity extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crime);
        FragmentManager fm = getSupportFragmentManager();
        Fragment fragment = fm.findFragmentById(R.id.fragment_container);
        if (fragment == null) {
            fragment = new CrimeFragment();
            fm.beginTransaction()
                .add(R.id.fragment_container, fragment)
                .commit();
        }
    }
}