创建列表明细应用1-使用fragment
笔记自《Android编程权威指南第二版》
第七章,创建一个列表明细应用
fragment是一种控制器对象,activity可委派它完成一些任务,这些任务通常就是管理用户界面。(管理用户界面的fragment又称UI fragment。它自己也产生布局文件)
利用fragment,可轻松实现选择不同的列表项就显示对应的明细视图Activity负责以一个明细fragment替换另一个明细fragment
托管可以这样理解,activity在其视图层级里提供一处位置来放置fragment的视图。fragment本身不具有在屏幕上显示视图的能力。
添加支持库:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8'
testCompile 'junit:junit:4.12'
compile 'com.android.support:support-v4:26.0.0-alpha1'
compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
}
项目结构:
Crime实体类:
package com.homelink.testcriminal; import java.util.Date;
import java.util.UUID; /**
* Created by ysc on 2017/9/30.
*/ public class Crime { private UUID mId;
private String mTitle;
private Date mDate;
private boolean mSolved;
public Crime() {
mId = UUID.randomUUID();
mDate = new Date();
} public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
} public Date getDate() {
return mDate;
}
public void setDate(Date date) {
mDate = date;
}
public boolean isSolved() {
return mSolved;
}
public void setSolved(boolean solved) {
mSolved = solved;
} }
SingleFragmentActivity抽象基类,用于CrimeActivity , CrimeListActivity。而这两个Activity又分别创建各自的Fragment
package com.homelink.testcriminal; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager; /**
* Created by ysc on 2017/9/30.
*/ public abstract class SingleFragmentActivity extends FragmentActivity { protected abstract Fragment createFragment(); @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
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();
}
} }
CrimeActitiy.java
package com.homelink.testcriminal; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.os.Bundle; public class CrimeActivity extends SingleFragmentActivity { @Override
protected Fragment createFragment() {
return new CrimeFragment();
}
}
CrimeListActivity.java
package com.homelink.testcriminal; import android.support.v4.app.Fragment; /**
* Created by ysc on 2017/9/30.
*/ public class CrimeListActivity extends SingleFragmentActivity { @Override
protected Fragment createFragment() {
return new CrimeListFragment();
}
}
activity_fragment.xml 的layout,用于托管fragment。很简单,就只放了一个FrameLayout,用于承载Fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.homelink.testcriminal.CrimeActivity"> <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"
/> </LinearLayout>
fragment_crime.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_title_label"
style="?android:listSeparatorTextViewStyle"
/>
<EditText android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="@string/crime_title_hint"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_details_label"
style="?android:listSeparatorTextViewStyle"
/>
<Button android:id="@+id/crime_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
/>
<CheckBox android:id="@+id/crime_solved"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:text="@string/crime_solved_label"
/>
</LinearLayout>
横向:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_title_label"
style="?android:listSeparatorTextViewStyle"
/>
<EditText android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:hint="@string/crime_title_hint"
/> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/crime_details_label"
style="?android:listSeparatorTextViewStyle"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" >
<Button
android:id="@+id/crime_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<CheckBox
android:id="@+id/crime_solved"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/crime_solved_label" />
</LinearLayout> </LinearLayout>
CrimeFragment.java控制器,展示数据
package com.homelink.testcriminal; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText; /**
* Created by ysc on 2017/9/30.
*/ public class CrimeFragment extends Fragment {
private Crime mCrime;
private EditText mTitleField; private Button mDateButton;
private CheckBox mSolvedCheckBox; @Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); mCrime = new Crime(); } @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable 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
}
}); mDateButton = (Button)v.findViewById(R.id.crime_date);
mDateButton.setText(mCrime.getDate().toString());
mDateButton.setEnabled(false); return v;
}
}
列表项的控制CrimeListFragment.java:
package com.homelink.testcriminal; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast; import java.util.List; /**
* Created by ysc on 2017/9/30.
*/ public class CrimeListFragment extends Fragment { private RecyclerView mCrimeRecyclerView; @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())); updateUI(); return view;
} private CrimeAdapter mAdapter;
private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes(); mAdapter = new CrimeAdapter(crimes);
mCrimeRecyclerView.setAdapter(mAdapter);
} private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private Crime mCrime; private TextView mTitleTextView;
private TextView mDateTextView;
private CheckBox mSolvedCheckBox; public CrimeHolder(View itemView) {
super(itemView); itemView.setOnClickListener(this);
mTitleTextView = (TextView) itemView.findViewById(R.id.list_item_crime_title_text_view);
mDateTextView = (TextView) itemView.findViewById(R.id.list_item_crime_date_text_view);
mSolvedCheckBox = (CheckBox)itemView.findViewById(R.id.list_item_crime_solved_check_box);
} public void BindCrime(Crime crime){
mCrime = crime;
mTitleTextView.setText(mCrime.getTitle());
mDateTextView.setText(mCrime.getDate().toString());
mSolvedCheckBox.setChecked(mCrime.isSolved());
} @Override
public void onClick(View view) {
Toast.makeText(getActivity(), mCrime.getTitle() + " clicked!", Toast.LENGTH_SHORT).show();
}
}
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
private List<Crime> mCrimes;
public CrimeAdapter(List<Crime> crimes) {
mCrimes = crimes;
} @Override
public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater.inflate(R.layout.list_item_crime, parent, false);
return new CrimeHolder(view);
}
@Override
public void onBindViewHolder(CrimeHolder holder, int position) {
Crime crime = mCrimes.get(position);
//holder.mTitleTextView.setText(crime.getTitle());
holder.BindCrime(crime);
}
@Override
public int getItemCount() {
return mCrimes.size();
}
} }
数据从哪里来,单例的CrimeLab.java
package com.homelink.testcriminal; import android.content.Context; import java.util.ArrayList;
import java.util.List;
import java.util.UUID; /**
* Created by ysc on 2017/9/30.
*/ public class CrimeLab { private static CrimeLab sCrimeLab;
public static CrimeLab get(Context context) {
if (sCrimeLab == null) {
sCrimeLab = new CrimeLab(context);
}
return sCrimeLab;
}
private CrimeLab(Context context) {
initCrimes();
} private List<Crime> mCrimes;
private void initCrimes(){
mCrimes = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Crime crime = new Crime();
crime.setTitle("Crime #" + i);
crime.setSolved(i % 2 == 0); // Every other one
mCrimes.add(crime);
}
} public List<Crime> getCrimes() {
return mCrimes;
}
public Crime getCrime(UUID id) {
for (Crime crime : mCrimes) {
if (crime.getId().equals(id)) {
return crime;
}
}
return null;
} }
如果是显示列表呢,使用recyclerview,fragment_crime_list.xml布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/crime_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
其中列表项:list_item_crime.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <CheckBox
android:id="@+id/list_item_crime_solved_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="4dp"/> <TextView
android:id="@+id/list_item_crime_title_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/list_item_crime_solved_check_box"
android:textStyle="bold"
android:padding="4dp"
tools:text="Crime Title"/> <TextView
android:id="@+id/list_item_crime_date_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/list_item_crime_solved_check_box"
android:layout_below="@id/list_item_crime_title_text_view"
android:padding="4dp"
tools:text="Crime Date"/> </RelativeLayout>
当然先修改一下AndroidManifest.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.homelink.testcriminal"> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"> <activity android:name=".CrimeListActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".CrimeActivity"> </activity>
</application> </manifest>
运行:
创建列表明细应用1-使用fragment的更多相关文章
- SharePoint2010新特性:InfoPath定义创建列表的界面
在SharePoint2007的时候,自定义的列表可以使用CAML修改其展示页面,但是对于创建列表的页面,不容易自定义.现在在SharePoint2010中,增强了InfoPath Form Serv ...
- 《Python CookBook2》 第四章 Python技巧 - 若列表中某元素存在则返回之 && 在无须共享引用的条件下创建列表的列表
若列表中某元素存在则返回之 任务: 你有一个列表L,还有一个索引号i,若i是有效索引时,返回L[i],若不是,则返回默认值v 解决方案: 列表支持双向索引,所以i可以为负数 >>> ...
- sharepoint 2010 使用自定义列表模版创建列表(2)
前面用的方法是通过界面上操作,根据自定义模版,创建的列表.sharepoint 2010 使用自定义列表模版创建列表(1) 这里顺便记录多另一种方法,通过程序来创建. ---------------- ...
- Android Material Design-Creating Lists and Cards(创建列表和卡)-(三)
转载请注明出处:http://blog.csdn.net/bbld_/article/details/40430319 翻译自:http://developer.android.com/trainin ...
- python 创建列表和向列表添加元素方法
今天的学习内容是python中的列表的相关内容. 一.创建列表 1.创建一个普通列表 >>> tabulation1 = ['大圣','天蓬','卷帘'] >>> ...
- python创建列表和向列表添加元素方法
今天的学习内容是python中的列表的相关内容. 一.创建列表 1.创建一个普通列表 >>> tabulation1 = ['大圣','天蓬','卷帘'] >>> ...
- SharePoint Online 创建列表库
前言 本文介绍如何在Office 365中创建列表库,以及列表库的一些基本设置. 正文 通过登录地址登录到Office 365的SharePoint Online站点中,我们可以在右上角的设置菜单中, ...
- 跟我学SharePoint 2013视频培训课程——怎样创建列表和列表项(7)
课程简介 第7天,怎样在SharePoint 2013中创建列表和列表项 视频 SharePoint 2013 交流群 41032413
- 【PyQt5 学习记录】011:使用 QListWidet 创建列表
使用 QListWidet 创建列表 作者: 八月未见 博客: https://www.cnblogs.com/jmtm/ 创建列表: list_widget = QListWidget() 插入项目 ...
随机推荐
- centos打开matlab的正确姿势
进入usr/local/MATLAB/R2015b/bin ./matlab
- .net core 生成
查看发布命令:dotnet publish --help 1:进入项目根目录 2:dotnet publish 或者发布到指定路劲 dotnet publish .\web.meb.scpr ...
- OperateResult 基础类及派生类介绍
前言 在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台输入下面的指令安装: Install-Package HslCommunication NuGet安 ...
- php之异常处理
<?php declare(strict_types = 1); function demo(int $v):int{ return 1; } try{ demo("1"); ...
- Semantic Compositionality through Recursive Matrix-Vector Spaces-paper
Semantic Compositionality through Recursive Matrix-Vector Spaces 作者信息:Richard Socher Brody Huval Chr ...
- BAT批处理文件,脚本时间值%time:~0,2%%time:~3,2%%time:~6,2%的用法。
最近公司的项目,需要部署一个oracle定时备份脚本,删除掉特定时间前的备份文件.BAT批处理文件结合windows系统(任务计划程序) 正常情况下我们的任务计划会有反馈数值,通过它可以判断这个任务计 ...
- CSS样式补充第二天
#p1{/* border-width: 1px;*/ /*边框实线*/ /*border-style: solid;*/ /*边框虚线*/ ...
- 初学版本控制更新Version control
概述: 在学习计算机软件工程中,修订控制是跟踪和控制源代码更改的任何类型的实践. 对于软件开发人员有时会使用修订控制软件来维护文档和配置文件以及源代码. 当团队设计,开发和部署软件时,通常会将同一软件 ...
- [c#]_ELVE_Message多功能用法
1. 当要显示如图3个按钮时,并要获得单击不同按钮的进行不同的相应时,可以在MessageBoxButtons后面添加一个.(应该英文的点,此处为了醒目,用中文代替)可以看到提示框下方需要几个按 ...
- session token两种登陆方式
Session 和 Token 其实Session和Token总体上还是很相似的,但是也有以下区别: 1. 过期时间:Session的过期时间存在cookie的Max-age字段,Token的过期时间 ...