2014-10-11 73 views
0

我有一個在開始時使用活動的應用程序。它正在加載一個xml文件來設置onStart程序的內容。之後,內容用一個讓用戶在EditText視圖中進行輸入的片段進行更改。該片段在運行時通過使用FragmentManager和Transaction進行動態加載。在這個片段中還有一個Button繼續。當用戶點擊按鈕時,其他內容將在該按鈕的onClick過程中加載。我嘗試用另一個名爲「ListFrag.java」的第一個片段替換,該列表使用名爲「list_frag.xml」的佈局文件。在肖像模式下,這個新的簡單的xml佈局,其中有一些視圖。用靜態片段替換活動內容

問題在設備處於橫向模式時開始。我用「getResources()。getConfiguration()。orientation」來檢查。此時我想用另一個版本的「list_frag.xml」更改開始片段「ListFrag.java」。因此,我把這個佈局放在一個名爲「layout-land」的新res文件夾中。此佈局爲左窗格定義了一個靜態片段,併爲右窗格定義了一個框架佈局。如果用戶點擊左側窗格中的項目,框架佈局將作爲裝載細節碎片的容器。

我真的不知道是否可以使用其中包含靜態片段定義的佈局來改變其上具有片段的活動的內容。我嘗試了一切,但沒有任何作品。可能在這裏有人有一個想法。

以下是項目中單個文件的源代碼。爲了縮短代碼我刪除了導入語句: MainActivity:

package com.example.wbslideshow; 

public class MainActivity extends Activity implements MainFrag.onstartFragBtnClickListener { 
    public static final String KEYVAL = "startpath"; 

    Bundle mySavedInstanceState; 
    MainFrag newMainFrag; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mySavedInstanceState = savedInstanceState; 

     //initialize the preferences from the xml-file 
     //if app is running the first time this will be taken from the xml-file 
     PreferenceManager.setDefaultValues(this, R.xml.preferences, false); 

     //load the MainFrag to select a path to the images and start-button 
     newMainFrag = new MainFrag(); 
     FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
     transaction.add(R.id.mycontainer, newMainFrag); 
     transaction.addToBackStack(null); 
     transaction.commit(); 

    } 

    //procedure from the interface of the MainFrag class to look for images in the given path 
    @Override 
    public void onstartFragBtnClicked(String root) 
    { 
     //call procedure "private boolean LandscapeMode()" to check the mode 
     if (!LandscapeMode()) 
     { 
      ListFrag newListFrag = new ListFrag(); 
      //put the value from the EditText field of MainFrag class into the arguments for the ListFrag class 
      Bundle args = new Bundle(); 
      args.putString(ListFrag.FRAG_MESSAGE_DEF_Input, root); 
      newListFrag.setArguments(args); 

      //change the fragments dynamically 
      FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
      transaction.replace(R.id.mycontainer, newListFrag); 
      transaction.addToBackStack(null); 
      transaction.commit(); 
     } 
     else 
     { 
      //remove the MainFrag 
      FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
      transaction.remove(newMainFrag); 
      transaction.commit(); 

      //load the static ListFrag 
      ListFrag newListFrag = new ListFrag(); 
      //put the value from the EditText field of MainFrag class into the arguments for the ListFrag class 
      Bundle args = new Bundle(); 
      args.putString(ListFrag.FRAG_MESSAGE_DEF_Input, root); 

      //load the ImgFrag for the right pane into the FrameLayout 
      ImgFrag myImgFrag = new ImgFrag(); 
      if (myImgFrag != null) 
      { 
       transaction = getFragmentManager().beginTransaction(); 
       transaction.add(R.id.myImgContainer, myImgFrag); 
       transaction.commit(); 
      } 
     } 
    } 

    private boolean LandscapeMode() { 
     if (getResources().getConfiguration().orientation == 
        Configuration.ORIENTATION_PORTRAIT) { 
      return false; 
      } 

     else 
      if (getResources().getConfiguration().orientation == 
       Configuration.ORIENTATION_LANDSCAPE) { 
       return true; 
     } else return false; 
    } 


} 

MainFrag: 包com.example.wbslideshow;

public class MainFrag extends Fragment implements OnClickListener{ //, OnSharedPreferenceChangeListener { 

    /* 
    * Constant is representing the value of the android:key from preferences.xml. 
    * This value is found in android:defaultValue 
    */ 
    public static final String KEYVAL = "startpath"; 
    public static final String JPGVAL = "pref-jpg"; 
    public static final String PNGVAL = "pref-png"; 

    EditText myEditText; 
    SharedPreferences sharedPref; 

    //define the interface to communicate with the main activity when user clicked the button 
    private onstartFragBtnClickListener mCallback; 
    public interface onstartFragBtnClickListener { 
     public void onstartFragBtnClicked(String myInput); 
    } 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle SavedInstanceState) { 
     View view = inflater.inflate(R.layout.main_frag, container, false); 

     //instantiate the start button and register the onClickListener 
     Button start = (Button) view.findViewById(R.id.startBtn); 
     start.setOnClickListener(this); 

     //read the current path to the pics from SharedPreferences file 
     Activity myActivity = getActivity(); 
     sharedPref = PreferenceManager.getDefaultSharedPreferences(myActivity.getBaseContext()); 

     //registerPreferenceListener(); 
     myEditText = (EditText) view.findViewById(R.id.inputSearchPath); 
     myEditText.setText(sharedPref.getString(KEYVAL, "/")); 
     return view; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     //read the current path to the pics from SharedPreferences file 
     Activity myActivity = getActivity(); 
     sharedPref = PreferenceManager.getDefaultSharedPreferences(myActivity.getBaseContext()); 
     myEditText.setText(sharedPref.getString(KEYVAL, "/")); 
    } 

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


    //change to ListFrag class if user clicked the button 
    @Override 
    public void onClick(View view) 
    { 
     Activity myActivity = getActivity(); 
     if (myActivity != null) 
     { 
      //Get the users input for to pass it to the activity 
      String root = ((EditText) myActivity.findViewById(
        R.id.inputSearchPath)).getText().toString(); 

      //Call the interface method in the activity to go on 
      mCallback.onstartFragBtnClicked(root); 
     } 
    } 

} 

ListFrag:

package com.example.wbslideshow; 
public class ListFrag extends ListFragment{ 

    ImageView image; 
    //Arrays to get files and folders 
    private List<String> listItem = null; 
    //TextView Object for the headline 
    private TextView TVmyPath; 
    //global variable taken the start path once 
    //used to compare when user clicked an item 
    private String g_startPath, g_myInput; 

    /* define a constant to take the passed input string from the start fragment */ 
    public static String FRAG_MESSAGE_DEF_Input = "com.example.wbslideshow.CALL_ListFragment"; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle SavedInstanceState) { 
     View myview = inflater.inflate(R.layout.list_frag, container, false); 
     TVmyPath = (TextView) myview.findViewById(R.id.startpath); 
     return myview; 
    } 

    @Override 
    public void onStart() 
    { 
     super.onStart(); 
     Activity myActivity = getActivity(); 

     //get an instance of the image and make it invisible 
     image = (ImageView) myActivity.findViewById(R.id.imageView1); 
     image.setVisibility(View.INVISIBLE); 

     Bundle args = getArguments(); 
     if (args != null) { g_startPath = args.getString(FRAG_MESSAGE_DEF_Input); } 

     //save the input the very first time to compare later with new item click 
     g_myInput = g_startPath; 

     getDir(g_startPath); 
    } 

    private void getDir(String p_startPath) 
    { 
     //set the headline 
     TVmyPath.setText("Location: " + p_startPath); 

     listItem = new ArrayList<String>(); 

     File f = new File(p_startPath); 
     //file array which get's all the folders and files from the input path 
     File[] files = f.listFiles(); 

     //startPath changed if user clicked a new folder 
     if(!g_myInput.equals(p_startPath)) 
     { 
      //alter g_myInput for the next comparison 
      g_myInput = p_startPath; 
      //put this item to make it possible to get one directory up 
      listItem.add("../"); 
     } 

     Arrays.sort(files, filecomparator); 

     for(int i=0; i < files.length; i++) 
     { 
      if(files[i].isFile()) 
      { 
       String filename = files[i].getName(); 
       //get the file extension 
       int z = filename.lastIndexOf('.'); 
       //read the file extension 
       String wbname = filename.substring(z+1); 
       if (wbname.equalsIgnoreCase("jpg")) {listItem.add(filename);} 
       if (wbname.equalsIgnoreCase("jpeg")) {listItem.add(filename);} 
      } 
      else {listItem.add(files[i].getName() + "/");} 
     } 
     ArrayAdapter<String> fileList = 
       new ArrayAdapter<String>(getActivity(), R.layout.row, listItem); 
     Activity myActivity = getActivity(); 
     ListView myList = (ListView) myActivity.findViewById(android.R.id.list); 
     myList.setAdapter(fileList); 
    } 

    //procedure to sort the arrays 
    Comparator<? super File> filecomparator = new Comparator<File>(){ 

     public int compare(File file1, File file2) { 
      if(file1.isDirectory()){ 
       if (file2.isDirectory()){ 
        return String.valueOf 
          (file1.getName().toLowerCase(Locale.getDefault())).compareTo 
          (file2.getName().toLowerCase(Locale.getDefault())); 
       }else{ 
        return -1; 
       } 
      }else { 
       if (file2.isDirectory()){ 
        return 1; 
       }else{ 
        return String.valueOf 
          (file1.getName().toLowerCase(Locale.getDefault())).compareTo 
          (file2.getName().toLowerCase(Locale.getDefault())); 
       } 
      } 
     } 
    }; 


    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) 
    { 
     File file; 
     //user clicked one path back 
     if (listItem.get(position) == "../") 
      { 
       file = new File(g_startPath); 
       g_startPath = file.getParent(); 
      } 
     else 
     //if user clicked to a picture or 
     //to a new folder (>> getDir has to be called with the new path) 
     //  >>file has to be set to path and position 
     {file = new File(g_startPath + '/' + listItem.get(position));} 

      Bitmap myBitmap; 
      //user clicked only to an image >> the image has to be shown in the image view - nothing else 
      if (file.isFile()) 
      { 
       //if(file.canRead()){ 
       myBitmap = BitmapFactory.decodeFile(file.getPath()); 
       image.setImageBitmap(myBitmap); 
       image.setVisibility(View.VISIBLE); 
       //} 
      }else 
      { 
       if (file.isDirectory()) 
       { 
         image.setVisibility(View.INVISIBLE); 
         if (listItem.get(position) != "../"){g_startPath = file.getPath();} 
         getDir(g_startPath); 
       } 
      } 
    } 
} 

ImgFrag:

package com.example.wbslideshow; 

public class ImgFrag extends Fragment{ 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
     View myImgView = inflater.inflate(R.layout.img_frag, container, false); 
     return myImgView; 
    } 

} 

佈局 activity_main.xml中

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#DA8306" 
    android:orientation="vertical" 
    android:id="@+id/mycontainer"> 

</LinearLayout 

main_frag.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/FragMain" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/startHeader" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/startHeader" /> 

    <EditText 
     android:id="@+id/inputSearchPath" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:ems="10" 
     android:hint="@string/startInputHint" > 

     <requestFocus /> 
    </EditText> 

    <Button 
     android:id="@+id/startBtn" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/startBtn" /> 

</LinearLayout> 

佈局/ list_frag.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:id="@+id/listFrag" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/startpath" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="#C27302" 
     android:height="40dp" 
     android:maxLines="1" 
     android:scrollHorizontally="false" 
     android:text="@string/list_header" 
     android:textSize="16sp" 
     android:textStyle="bold" /> 

    <ListView 
     android:id="@android:id/list" 
     android:layout_width="match_parent" 
     android:layout_height="312dp" 
     android:layout_gravity="fill" 
     android:background="#B012EB" /> 

    <TextView 
     android:id="@+id/empty" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@drawable/abc_ab_bottom_solid_dark_holo" /> 

     <FrameLayout 
     android:id="@+id/myImgContainer" 
     android:layout_weight="2" 
     android:layout_width="0dp" 
     android:layout_height="fill_parent" 
     /> 

</LinearLayout> 

佈局,土地/ list_frag.xml:

<?xml version="1.0" encoding="utf-8"?> 
LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:baselineAligned="false" 
    android:orientation="horizontal" > 

    <!-- static fragment for the left pane --> 
    <fragment 
     android:name="com.example.wbslideshow.ListFrag" 
     android:id="@+id/listFrag" 
     android:layout_width="0dp" 
     android:layout_height="fill_parent" 
     android:layout_weight="1" /> 

    <FrameLayout 
     android:id="@+id/myImgContainer" 
     android:layout_weight="2" 
     android:layout_width="0dp" 
     android:layout_height="fill_parent"> 
    </FrameLayout> 

</LinearLayout> 

img_frag.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="horizontal" 
    android:id="@+id/imgFrag"> 

     <ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@drawable/abc_ab_bottom_solid_dark_holo" /> 


</LinearLayout> 

的代碼可能不是完美但這不是這裏的問題。在肖像模式下,該應用程序正在工作。只有在橫向模式下,我加載listfrag時出現問題。 這裏也是當前的logcat:

10-11 13:20:12.563:W/dalvikvm(5158):線程ID = 1:螺紋與未捕獲的異常(組= 0x414539a8) 10-11 13退出: 20:12.583:E/AndroidRuntime(5158):致命例外:主 10-11 13:20:12.583:E/AndroidRuntime(5158):java.lang。IllegalArgumentException:未找到id 0x7f060041(com.example.wbslideshow:id/myImgContainer)的片段ImgFrag {417af140#1 id = 0x7f060041} 10-11 13:20:12.583:E/AndroidRuntime(5158):at android。在Android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057) 10-11 13:13:20:12.583:E/AndroidRuntime(5158):app.FragmentManagerImpl.moveToState(FragmentManager.java:877) 10-11 13:20: 20:12.583:E/AndroidRuntime(5158):在android.app.BackStackRecord.run(BackStackRecord.java:694) 10-11 13:20:12.583:E/AndroidRuntime(5158):在android.app.FragmentManagerImpl。 execPendingActions(FragmentManager.java:1435) 10-11 13:20:12.583:E/AndroidRuntime(5158):at android.app.FragmentManagerImpl $ 1.run(FragmentManager.java:441) 10-11 13:20:12.583 :E/AndroidRuntime(5158):在android.os.Handler.handleCall (Handler.java:725) 10-11 13:20:12.583:E/AndroidRuntime(5158):at android.os.Handler.dispatchMessage(Handler.java:92) 10-11 13:20:12.583: E/AndroidRuntime(5158):在android.os.Looper.loop(Looper.java:153) 10-11 13:20:12.583:E/AndroidRuntime(5158):at android.app.ActivityThread.main(ActivityThread。 java:5299) 10-11 13:20:12.583:E/AndroidRuntime(5158):at java.lang.reflect.Method.invokeNative(Native Method) 10-11 13:20:12.583:E/AndroidRuntime(5158) ):at java.lang.reflect.Method.invoke(Method.java:511) 10-11 13:20:12.583:E/AndroidRuntime(5158):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:833) 10-11 13:20:12.583:E/AndroidRuntime(5158):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 10-11 13:20:12.583:E/AndroidRuntime(5158):在dalvik.system.NativeStart.main(本機方法)

我可以看到有「無VIE發現一個問題... 「但我不知道爲什麼。對我來說,似乎是來自res/layout-land的佈局文件未在橫向模式下加載,因此IMgFrag的onCreateView會出現問題。 但是爲什麼?

安德烈亞斯

回答

0

ID myImgContainer在佈局layout-land/list_frag.xml可用,通過單擊事件被調用的時候,只有main_frag將在屏幕上MainActivity用戶R.id.mycontainer顯示自己,所以不是R.id.myImgContainer

+0

嗨Dinash,非常感謝您的回答。但這並沒有奏效。如果我按照您的建議,當我從縱向更改爲橫向時,LstFrag未加載。如果我從橫向開始,只能看到非常小的ImageView,但沒有列表。我認爲這是行不通的:如果沒有id(沒有容器),靜態片段應該去哪裏以及ImageView應該到哪裏? 或者可能是我沒有以正確的方式得到你的想法。儘管如此,任何感謝迄今 安德烈亞斯 – 2014-10-13 07:52:54

0

您不應該在layout-land/list_frag.xml文件中使用類似fragment的標籤。

list_frag.xml是ListFrag類的佈局。您嘗試將ListFrag放入它自己的佈局文件中。這是錯誤的。

在橫向模式下,您是否想要在縱向模式下的ImageView下方的列表和位於列表右側的ImageView(如兩個面板)?

如果你想這樣做。你只需要如下寫你的佈局,土地/ list_frag.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="horizontal"> 

    <LinearLayout 
     android:id="@+id/listFrag" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight="1" 
     android:orientation="vertical"> 

     <TextView 
      android:id="@+id/startpath" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:height="40dp" 
      android:background="#C27302" 
      android:maxLines="1" 
      android:scrollHorizontally="false" 
      android:text="@string/list_header" 
      android:textSize="16sp" 
      android:textStyle="bold" /> 

     <ListView 
      android:id="@android:id/list" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_gravity="fill" 
      android:background="#B012EB" /> 

     <TextView 
      android:id="@+id/empty" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 
    </LinearLayout> 


    <FrameLayout 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight="2" 
     android:orientation="vertical"> 

     <ImageView 
      android:id="@+id/imageView1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center" 
      android:src="@drawable/abc_ab_bottom_solid_dark_holo" /> 
    </FrameLayout> 

</LinearLayout> 

你不需要的myImgContainer,所以從您的佈局/ list_frag.xml其刪除:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/listFrag" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <TextView 
     android:id="@+id/startpath" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:height="40dp" 
     android:background="#C27302" 
     android:maxLines="1" 
     android:scrollHorizontally="false" 
     android:text="@string/list_header" 
     android:textSize="16sp" 
     android:textStyle="bold" /> 

    <ListView 
     android:id="@android:id/list" 
     android:layout_width="match_parent" 
     android:layout_height="312dp" 
     android:layout_gravity="fill" 
     android:background="#B012EB" /> 

    <TextView 
     android:id="@+id/empty" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <ImageView 
     android:id="@+id/imageView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@drawable/abc_ab_bottom_solid_dark_holo" /> 

</LinearLayout> 

變化onstartFragBtnClicked方法MainActivity,只能用ListFrag替換。該平臺將負責將哪個xml文件用作ListFrag的佈局。

public void onstartFragBtnClicked(String root) 
{ 
    ListFrag newListFrag = new ListFrag(); 
    Bundle args = new Bundle(); 
    args.putString(ListFrag.FRAG_MESSAGE_DEF_Input, root); 
    newListFrag.setArguments(args); 

    //change the fragments dynamically 
    FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
    transaction.replace(R.id.mycontainer, newListFrag); 
    transaction.addToBackStack(null); 
    transaction.commit(); 
} 
+0

嗨鳳黛,好方法,它的工作到目前爲止。但這裏有兩件事我不喜歡: - 我必須觸摸兩次按鈕才能啓動ListFrag。與Android返回鍵一樣。可能有一個概率。與後臺。 - 對於像我提到的應用程序可以。但是如果還有另一種意圖,比如讓右邊的碎片爲左邊的碎片提供信息?一個列表正在按照它自己的方式組織對某個項目的點擊,但我對這種情況下的2個碎片的解決方案感興趣。 但你已經幫我解決了我在我的問題中描述的情況 - 謝謝! – 2014-10-13 08:10:16

+0

一些額外的想法:在過程「onOptionsItemSelected」中爲右側調用片段是否可以?但我想這不是很正確或?對不起 - 但你看到我對Android App編程有點新鮮感! – 2014-10-13 08:13:27

+0

爲什麼你必須觸摸兩次按鈕才能啓動ListFrag?任何其他信息的問題? – 2014-10-13 09:02:39