Android编程权威指南 - 第10章 使用fragment

2016-12-08  本文已影响487人  JMasche

目标

本章的目标效果是,在列表中点击一项,弹出明细fragment界面。
此界面可以修改后,并保存返回列表fragment界面。
类的调用关系如下:

类调用关系

启动明细界面CrimeFragment

CrimeListFragment类中启动调用

具体代码如下

@Override
public void onListItemClick(ListView a, View v, int position, long id) {    
      Crime c = ((CrimeAdapter)getListAdapter()).getItem(position);    
      Log.d(TAG, c.getTitle() + " was clicked.");    

      // Start CrimeActivity    
      Intent i = new Intent(getActivity(), CrimeActivity.class);    
      i.putExtra(CrimeFragment.EXTRA_CRIME_ID, c.getId());    
      startActivity(i);
}

CrimeFragment类的设计

获取Intent内容

和Activity一样,通过activity的getSerializableExtra来获得Intent传递的对象

UUID crimeId = (UUID)this.getIntent().getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);

获取Intent并处理的设计

在哪获取Intent传递的消息信息?
我们可以直接在CrimeFragment类中使用上面的代码获取Intent的内容,并生成具体的Crime对象,然后刷新明细界面。
但是这样做的问题在于,牺牲了CrimeFragment的封装性,使得其无法再被其他的activity进行调用。
所以,我们应该在Activity就处理掉Intent信息,并将获取的信息作为参数传递给Fragment。传递此参数的对象就是Bundle。

用于传递参数的Bundle对象

最终的设计

public static CrimeFragment newInstance(UUID crimeId) {    
      Bundle args = new Bundle();    
      args.putSerializable(EXTRA_CRIME_ID, crimeId);    
      
      CrimeFragment fragment = new CrimeFragment();    
      fragment.setArguments(args);    

      return fragment;
}
public class CrimeActivity extends SingleFragmentActivity {    
      @Override    
      protected Fragment createFragment() {        
            UUID crimeId = (UUID)this.getIntent().getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);        
            
            return CrimeFragment.newInstance(crimeId);    
      }
}
@Override
public void onCreate(Bundle savedInstanceState) {    
      super.onCreate(savedInstanceState);    
      
      UUID crimeId = (UUID)getArguments().getSerializable(EXTRA_CRIME_ID);    
      mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
      View v = inflater.inflate(R.layout.fragment_crime, parent, false);

      mTitleField = (EditText)v.findViewById(R.id.crime_title);
      mTitleField.setText(mCrime.getTitle());

      ..........................................................

      mSolvedCheckBox = (CheckBox)v.findViewById(R.id.crime_solved);
      mSolvedCheckBox.setChecked(mCrime.isSolved());

      ...........................................................

      return v;
}

最终效果

选中列表的Cime 4点击,出现如下明细界面

明细界面

列表界面显示明细的修改

((CrimeAdapter)getListAdapter()).notifyDataSetChanged();

这确实挺神奇的,毕竟在明细界面完全没有配置相关代码,Adapter是需要好好研究的类。

@Override
public void onResume() {    
      super.onResume();        
      ((CrimeAdapter)getListAdapter()).notifyDataSetChanged();
}

通过fragment获取返回结果

public class CrimeListFragment extends ListFragment {
      private ArrayList<Crime> mCrimes;
      private static final String TAG = "CrimeListFragment";
      private static final int REQUEST_CRIME = 1;

      @Override
      public void onListItemClick(ListView a, View v, int position, long id) {    
            Crime c = ((CrimeAdapter)getListAdapter()).getItem(position);    
            Log.d(TAG, c.getTitle() + " was clicked.");    

            // Start CrimeActivity    
            Intent i = new Intent(getActivity(), CrimeActivity.class);    
            i.putExtra(CrimeFragment.EXTRA_CRIME_ID, c.getId());    
            startActivityForResult(i, REQUEST_CRIME);
      }

      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) {    
            if (requestCode == REQUEST_CRIME) {       
                  // Handle result    
            }
      }
}
public class CrimeFragment extends Fragment {

      public void returnResult() {    
            getActivity().setResult(Activity.RESULT_OK, null);
      }
}

具体的应用在20章才会详细介绍*

更新后的程序结构图

更新后的程序结构图
上一篇下一篇

猜你喜欢

热点阅读