2014-03-29 41 views
6

我完成了Android手持系統編程移動應用程序Coursera課程。 該課程的示例代碼之一告訴我們如何爲我們提供片段。基本上它是把屏幕分成兩個片段,一個用於書名,另一個用於書中的引用。如果用戶點擊左側片段中的標題,則該書中關聯的引用將顯示在右側的片段中。碎片中的super.onCreateView

這是爲在MainActivity的代碼:

package course.examples.Fragments.StaticLayout; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 
import course.examples.Fragments.StaticLayout.TitlesFragment.ListSelectionListener; 

public class QuoteViewerActivity extends Activity implements 
     ListSelectionListener { 

    public static String[] mTitleArray; 
    public static String[] mQuoteArray; 
    private QuotesFragment mDetailsFragment; 

    private static final String TAG = "QuoteViewerActivity"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mTitleArray = getResources().getStringArray(R.array.Titles);  
     mQuoteArray = getResources().getStringArray(R.array.Quotes); 

     setContentView(R.layout.main); 

     mDetailsFragment = (QuotesFragment) getFragmentManager() 
       .findFragmentById(R.id.details);   
    } 

    @Override 
    public void onListSelection(int index) { 
     if (mDetailsFragment.getShownIndex() != index) {   
      mDetailsFragment.showQuoteAtIndex(index); 
     } 
    } 

這是引用片段的代碼:

package course.examples.Fragments.StaticLayout; 

import android.app.Activity; 
import android.app.Fragment; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

public class QuotesFragment extends Fragment { 

    private TextView mQuoteView = null; 
    private int mCurrIdx = -1; 
    private int mQuoteArrayLen; 

    private static final String TAG = "QuotesFragment"; 

    public int getShownIndex() { 
     return mCurrIdx; 
    } 

    public void showQuoteAtIndex(int newIndex) { 
     if (newIndex < 0 || newIndex >= mQuoteArrayLen) 
      return; 
     mCurrIdx = newIndex; 
     mQuoteView.setText(QuoteViewerActivity.mQuoteArray[mCurrIdx]); 
    } 
@Override 
public void onAttach(Activity activity) { 
    Log.i(TAG, getClass().getSimpleName() + ":entered onAttach()"); 
    super.onAttach(activity); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    Log.i(TAG, getClass().getSimpleName() + ":entered onCreate()"); 
    super.onCreate(savedInstanceState); 
} 

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

@Override 
public void onActivityCreated(Bundle savedInstanceState) {  
    super.onActivityCreated(savedInstanceState); 
    mQuoteView = (TextView) getActivity().findViewById(R.id.quoteView); 
    mQuoteArrayLen = QuoteViewerActivity.mQuoteArray.length; 
} 

這是爲標題片段的代碼:

package course.examples.Fragments.StaticLayout; 

import android.app.Activity; 
import android.app.ListFragment; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 

public class TitlesFragment extends ListFragment { 
    private ListSelectionListener mListener = null; 
    private static final String TAG = "TitlesFragment"; 

    public interface ListSelectionListener { 
     public void onListSelection(int index);  
    } 

    @Override 
    public void onListItemClick(ListView l, View v, int pos, long id) { 
     getListView().setItemChecked(pos, true); 
     mListener.onListSelection(pos); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     try { 
      mListener = (ListSelectionListener) activity; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() 
        + " must implement OnArticleSelectedListener"); 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     Log.i(TAG, getClass().getSimpleName() + ":entered onCreate()"); 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     Log.i(TAG, getClass().getSimpleName() + ":entered onCreate()"); 

     **return super.onCreateView(inflater, container, savedInstanceState);** 

    } 

    @Override 
    public void onActivityCreated(Bundle savedState) { 
     super.onActivityCreated(savedState); 

     getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
     setListAdapter(new ArrayAdapter<String>(getActivity(), 
       R.layout.title_item, QuoteViewerActivity.mTitleArray)); 
    } 

MainActivity 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="match_parent" 
    android:baselineAligned="false" 
    android:orientation="horizontal" > 

    <fragment 
     android:id="@+id/titles" 
     android:layout_width="0px" 
     android:layout_height="match_parent" 
     android:layout_weight="1" 
     class="course.examples.Fragments.StaticLayout.TitlesFragment" /> 

    <fragment 
     android:id="@+id/details" 
     android:layout_width="0px" 
     android:layout_height="match_parent" 
     android:layout_weight="2" 
     class="course.examples.Fragments.StaticLayout.QuotesFragment" /> 

</LinearLayout> 

報價片斷的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="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/quoteView" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:padding="5dip" 
     android:textSize="32sp" > 
    </TextView> 
</LinearLayout> 

標題片段XML

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="?android:attr/activatedBackgroundIndicator" 
    android:orientation="vertical" 
    android:padding="5dip" 
    android:textSize="32sp" > 

</TextView> 

我的問題是爲什麼onCreat下的方法eView在引用片段和標題片段下有所不同? QuoteFragment是return inflater.inflate(R.layout.quote_fragment,container,false); 標題片段爲return super.onCreateView(inflater,container,savedInstanceState);

+0

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.2_r1/android/app/ListFragment.java /。檢查源代碼 – Raghunandan

+0

Raghunandan,你知道android如何知道它必須將標題片段膨脹到main.xml中嗎?在引用片段的代碼中,我們有mDetailsFragment =(QuotesFragment)getFragmentManager()。findFragmentById(R.id.details)。標題片段沒有類似的代碼。我的猜測是,主要的activity.xml引用它通過class =「course.examples.Fragments.StaticLayout.TitlesFragment」因此它膨脹了它,但我不知道... – Simon

+0

是的,請問一個新的問題,我會回答 – Raghunandan

回答

9

因爲QuotesFragment延伸Fragment默認情況下沒有佈局,用戶必須膨脹並返回自己的佈局。這是一個FragmentonCreateView方法的樣子:

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
    return null; 
} 

TitlesFragment延伸ListFragment,默認情況下,它包含ListView的項目,TextView一個標籤,當列表爲空,ProgressBar有一個佈局。在這種情況下,用戶不必返回他自己的視圖,並可以返回超級調用獲得的對象。在ListFragmentonCreateView

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    return inflater.inflate(com.android.internal.R.layout.list_content, 
      container, false); 
} 
+0

非常感謝解釋,這使得很多感覺! – Simon

+0

@Simon其實你可以在ListFragment中刪除'onCreateView' – Raghunandan

1

因爲ListFragment已經有一個默認佈局,只包含它使用的ListView。您可以像使用其他Fragment一樣膨脹自定義佈局,但這不是必需的。如果您只是想使用ListView,則可以返回super.onCreateView(...)

如果你想使用你必須記住要使用該ID爲您ListView自定義佈局:

android:id="@android:id/list" 
1

你有

return super.onCreateView(inflater, container, savedInstanceState); 

ListFragment有由一個默認佈局單列表視圖。因此,如果您不希望在屏幕上顯示任何其他視圖,則無需對自定義佈局進行充氣。

看看ListFragment的來源。您的Fragment課程延伸ListFragment

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.2_r1/android/app/ListFragment.java/

189 
190 @Override 
191 public View onCreateView(LayoutInflater inflater, ViewGroup container, 
192   Bundle savedInstanceState) { 
193  return inflater.inflate(com.android.internal.R.layout.list_content, 
194    container, false); 
195 } 

193線表示默認佈局充氣

而且你有

public class QuotesFragment extends Fragment { 

return inflater.inflate(R.layout.quote_fragment, container, false); 

你在做什麼被稱爲膨脹的自定義佈局quote_fragment.xml

編輯:

假設你想顯示ListFragment需要充氣自定義佈局等意見。並且該佈局必須具有ListFragment,其編號爲@android:id/list

+0

感謝您的解釋,這很有道理! – Simon

+1

@Simon其實你可以擺脫'ListFragment'中的'onCreateView',它不會影響代碼 – Raghunandan

+0

嗯......你是對的Raghunandan!我只是在AVD上測試它,它對應用程序沒有影響。我不知道爲什麼課程協調員把它放在代碼中,然後......可能向我們展示片段類的生命週期以及混淆新手哈哈。 – Simon