2014-10-11 55 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