Android编程权威指南 第3版 第17、18章 学习总结
代码来源于《Android编程权威指南》第三版
14-4F-8A-A2-D1-90 60 9
14-4F-8A-A2-D1-90 60 10
以下操作基于上一个blog已完成的基础上进行的
双版面主从用户界面
为了适应平板设备,我们改造CriminalIntent应用的用户界面,让用户能同时看到列表和明细界面并与它们交互。图17-1展示了这样的列表明细界面,也可称其为主从用户界面( master- detail interface )。
我们首先创建一个平板,打开AVD Manager,新建一个设备,在Tablet里选择一个模拟器,列表里的版本都可以,安装完成后,就可以进行代码的更改了
要实现双版面布局,需完成如下任务:
●修改SingleF ragmentActivity,不再硬编码实例化布局;
●创建包含两个fragment容器的布局;
●修改CrimeListActivity,实现在手机设备上实例化单版面布局,在平板设备上实例化双版面布局。
更改后的完整代码如下,其余的具体步骤依照书上来,有不懂的代码请参考书本第17章的内容。
SingleeFragmentActivity.java
public abstract class SingleFragmentActivity extends AppCompatActivity {
protected abstract Fragment createFragment();
@LayoutRes
protected int getLayoutResId() {
return R.layout.activity_fragment;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResId());
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
}
res/layout/activity_twopane.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:attr/dividerHorizontal"
android:orientation="horizontal"
android:showDividers="middle">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="@+id/detail_fragment_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
CrimeListActivity.java
public class CrimeListActivity extends SingleFragmentActivity
implements CrimeListFragment.Callbacks, CrimeFragment.Callbacks {
@Override
protected Fragment createFragment() {
return new CrimeListFragment();
}
@Override
protected int getLayoutResId() {
return R.layout.activity_masterdetail;
}
@Override
public void onCrimeSelected(Crime crime) {
if (findViewById(R.id.detail_fragment_container) == null) {
Intent intent = CrimePagerActivity.newIntent(this, crime.getId());
startActivity(intent);
} else {
Fragment newDetail = CrimeFragment.newInstance(crime.getId());
getSupportFragmentManager().beginTransaction()
.replace(R.id.detail_fragment_container, newDetail)
.commit();
}
}
public void onCrimeUpdated(Crime crime) {
CrimeListFragment listFragment = (CrimeListFragment)
getSupportFragmentManager()
.findFragmentById(R.id.fragment_container);
listFragment.updateUI();
}
}
res/values/refs.xml
<resources>
<item name="activity_masterdetail" type="layout">@layout/activity_fragment</item>
</resources>
因为res/values/目录中的别名资源是系统默认的别名资源,所以CrimeListActivity生成 了单版面布局。
现在,创建一个大屏幕设备专用的可选别名资源,让activity_masterdetail别名资源指向activity_twopane.xml双版面布局资源。
在项目工具窗口中,右键单击res/values/目录,弹出如图17-6所示的新建资源文件窗口。按照下图设置,用>>按钮把Available qualifers窗口中的Screen Width选到右边窗口去。
res/values-w600dp/refs.xml
<resources>
<item name="activity_masterdetail" type="layout">@layout/activity_twopane</item>
</resources>
CrimeListFragment.java
public class CrimeListFragment extends Fragment {
private static final String SAVED_SUBTITLE_VISIBLE = "subtitle";
private RecyclerView mCrimeRecyclerView;
private CrimeAdapter mAdapter;
private boolean mSubtitleVisible;
private Callbacks mCallbacks;
/**
* Required interface for hosting activities.
*/
public interface Callbacks {
void onCrimeSelected(Crime crime);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mCallbacks = (Callbacks) context;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_crime_list, container, false);
mCrimeRecyclerView = (RecyclerView) view
.findViewById(R.id.crime_recycler_view);
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
if (savedInstanceState != null) {
mSubtitleVisible = savedInstanceState.getBoolean(SAVED_SUBTITLE_VISIBLE);
}
updateUI();
return view;
}
@Override
public void onResume() {
super.