本次要講的內容是利用RecyclerView顯示Users串列的資訊,如下圖所示,

首先我們來創建模型User.java
package com.example.mytest.User;
import java.util.UUID;
public class User{
private UUID mId;
private String name;
public User() {
this(UUID.randomUUID());
}
public User(UUID id){
mId=id;
}
public UUID getId() {
return mId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"mId=" + mId +
", name='" + name + '\'' +
'}';
}
}
創建單例UserLab.java
user陣列物件將存盤在一個單例里,單例是特殊的Java類,在創建實體時,一個單例類僅允許創建一個實體,
應用能在記憶體里存活多久,單例就能活多久,
package com.example.mytest.User;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class UserLab {
private static UserLab sUserLab;
private List<User> mUsers;//保存User物件
//get()方法
public static UserLab get(Context context){
//如果實體存在直接回傳它,如果不存在,呼叫構造方法創建它
if (sUserLab==null){
sUserLab=new UserLab(context);
}
return sUserLab;
}
//私有構造方法
private UserLab(Context context){
mUsers=new ArrayList<>();
//先批量存入100個User物件
for (int i=0;i<100;i++){
User user=new User();
user.setName("User #"+i);
mUsers.add(user);
}
}
public List<User> getUsers(){
return mUsers;
}
public User getUser(UUID id){
for (User user:mUsers){
if (user.getId().equals(id)){
return user;
}
}
return null;
}
}
創建通用型fragment托管布局activity_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:layout_
android:layout_height="match_parent"
tools:context="com.example.mytest.User.UserActivity">
</FrameLayout>
抽象activity類,創建SingleFragmentActivity.java
因為這段代碼很通用,所以抽取出來,便于簡化代碼,
package com.example.mytest.User;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import com.example.mytest.R;
public abstract class SingleFragmentActivity extends AppCompatActivity {
protected abstract Fragment createFragment();
@Override
protected 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();
}
}
}
創建UserListActivity.java
繼承SingleFragmentActivity類,托管UserListFragment
package com.example.mytest.User;
import android.support.v4.app.Fragment;
public class UserListActivity extends SingleFragmentActivity {
@Override
protected Fragment createFragment() {
return new UserListFragment();
}
}
創建UserListFragment .java
public class UserListFragment extends Fragment {
}
在組態檔AndroidManifest.xml中宣告UserListActivity為launcher acticity
<activity android:name=".User.UserListActivity">
<!--添加這里開始-->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!--添加這里結束-->
</activity>
現在運行應用,會看到UserListActivity的FrameLayout托管了一個無內容的UserListFragment,
我們需要UserListFragment向用戶展示user串列,這就要用到RecyclerView類,RecyclerView是ViewGroup的子類,每一個串列項都是作為一個View子物件顯示的,
一次為所有串列項創建View很容易搞垮應用,按需創建視圖物件才是比較合理的解決方案,RecyclerView顧名思義就是回收再利用,用戶滑動螢屏切換視圖時,上一個視圖會回收利用,當然整個功能的實作還需要ViewHolder子類和Adapter子類的支持,
- RecyclerView的任務僅限于回收和定位螢屏上的View,
- ViewHolder只做一件事:容納View視圖,
- Adapter創建必要的ViewHolder,系結ViewHolder至模型層資料,
現在我們來正式使用RecyclerView,
1. 添加RecyclerView依賴庫
dependencies {
...
compile 'com.android.support:recyclerview-v7:25.3.1'
}
2.新建fragment_user_list.xml布局檔案,
修改根視圖為RecyclerView,并為其配置ID
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/user_recycler_view"
android:layout_
android:layout_height="match_parent"
android:orientation="vertical">
</android.support.v7.widget.RecyclerView>
3.視圖和fragment關聯
修改UserListFragment類檔案,使用布局并找到布局中的RecyclerView視圖,
注意,沒有LayoutManager的支持,不僅RecyclerView無法作業,還會導致應用崩潰,所以,RecyclerView視圖創建完成后,就立即轉交給了Manager物件,LayoutManager負責螢屏上串列項的擺放、定義螢屏滾動行為,
public class UserListFragment extends Fragment {
private RecyclerView mUserRecyclerView;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_user_list,container,false);
mUserRecyclerView=(RecyclerView)view.findViewById(R.id.user_recycler_view);
mUserRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
}
4.實作ViewHolder和Adapter
public class UserListFragment extends Fragment {
........
//定義ViewHolder內部類,它會實體化并使用list_item_user布局
private class UserHolder extends RecyclerView.ViewHolder{
private User mUser;
//構造方法
public UserHolder(LayoutInflater inflater,ViewGroup parent){
super(inflater.inflate(R.layout.list_item_user,parent,false));
}
}
//創建Adapter內部類
private class UserAdapter extends RecyclerView.Adapter<UserHolder>{
private List<User> mUsers;
public UserAdapter(List<User> users){
mUsers=users;
}
@Override
public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(getActivity());
return new UserHolder(layoutInflater,parent);
}
@Override
public void onBindViewHolder(UserHolder holder, int position) {
}
@Override
public int getItemCount() {
return mUsers.size();
}
}
}
新建updateUI方法,關聯Adapter和RecyclerView,
public class UserListFragment extends Fragment {
......
private UserAdapter mAdapter;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_user_list,container,false);
mUserRecyclerView=(RecyclerView)view.findViewById(R.id.user_recycler_view);
mUserRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
private void updateUI() {
UserLab userLab=UserLab.get(getActivity());
List<User> users=userLab.getUsers();
mAdapter=new UserAdapter(users);
mUserRecyclerView.setAdapter(mAdapter);
}
......
}
運行應用,結果如圖所示,

現在系結串列項,使呈現不同的資料,
我們把系結作業放入UserHolder類里,系結之前首先要實體化相關組件,由于是一次性任務,因此直接放在構造方法里處理,然后定義bind(User)方法,每次有新的User要在UserHolder中顯示時,都要呼叫它一次,
為了錦上添花,這里還設定了串列項點擊后彈出小的提示框,通過實作View.OnClickListener介面來實作這個功能,
//定義ViewHolder內部類,它會實體化并使用list_item_user布局
private class UserHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView mNameTextView;
private User mUser;
//構造方法
public UserHolder(LayoutInflater inflater,ViewGroup parent){
super(inflater.inflate(R.layout.list_item_user,parent,false));
//檢測用戶點擊事件
itemView.setOnClickListener(this);//點擊了則呼叫onClick()方法
//實體化視圖組件
mNameTextView=(TextView) itemView.findViewById(R.id.user_name);
}
//每次有新的User要在UserHolder中顯示時,都要呼叫它一次
public void bind(User user){
mUser=user;
mNameTextView.setText(mUser.getName());
}
@Override
public void onClick(View v) {
Toast.makeText(getActivity(),mUser.getName()+" clicked!",Toast.LENGTH_SHORT).show();
}
}
//創建Adapter內部類
private class UserAdapter extends RecyclerView.Adapter<UserHolder>{
.........
@Override
public void onBindViewHolder(UserHolder holder, int position) {
User user=mUsers.get(position);
holder.bind(user);
}
........
}
這里為了方便大家的閱讀,再次提供UserListFragment.java的全部代碼,
package com.example.mytest.User;
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.TextView;
import android.widget.Toast;
import com.example.mytest.R;
import java.util.List;
public class UserListFragment extends Fragment {
private RecyclerView mUserRecyclerView;
private UserAdapter mAdapter;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_user_list,container,false);
mUserRecyclerView=(RecyclerView)view.findViewById(R.id.user_recycler_view);
mUserRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
private void updateUI() {
UserLab userLab=UserLab.get(getActivity());
List<User> users=userLab.getUsers();
mAdapter=new UserAdapter(users);
mUserRecyclerView.setAdapter(mAdapter);
}
//定義ViewHolder內部類,它會實體化并使用list_item_user布局
private class UserHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private TextView mNameTextView;
private User mUser;
//構造方法
public UserHolder(LayoutInflater inflater,ViewGroup parent){
super(inflater.inflate(R.layout.list_item_user,parent,false));
//檢測用戶點擊事件
itemView.setOnClickListener(this);//點擊了則呼叫onClick()方法
//實體化視圖組件
mNameTextView=(TextView) itemView.findViewById(R.id.user_name);
}
//每次有新的User要在UserHolder中顯示時,都要呼叫它一次
public void bind(User user){
/* mUser=user;
mNameTextView.setText(mUser.getName());*/
}
@Override
public void onClick(View v) {
Toast.makeText(getActivity(),mUser.getName()+" clicked!",Toast.LENGTH_SHORT).show();
}
}
//創建Adapter內部類
private class UserAdapter extends RecyclerView.Adapter<UserHolder>{
private List<User> mUsers;
public UserAdapter(List<User> users){
mUsers=users;
}
@Override
public UserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(getActivity());
return new UserHolder(layoutInflater,parent);
}
@Override
public void onBindViewHolder(UserHolder holder, int position) {
User user=mUsers.get(position);
holder.bind(user);
}
@Override
public int getItemCount() {
return mUsers.size();
}
}
}
現在再次運行程式,效果如下圖,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/467110.html
標籤:其他
