用静态片段替换活动内容

时间:2014-10-11 05:56:23

标签: android android-layout android-fragments

我有一个在开始时使用活动的应用。它正在加载一个xml文件来设置onStart-procedure的内容。之后,使用片段更改内容,该片段允许用户在EditText视图中进行输入。通过使用FragmentManager和Transaction在运行时动态加载此片段。此片段还有一个按钮可以继续。当用户单击该按钮时,在该按钮的onClick过程中加载另一个内容。我试图用另一个名为“ListFrag.java”的片段替换第一个片段,该片段使用名为“list_frag.xml”的布局文件。在纵向模式下,这是一个简单的xml布局,上面有一些视图。

当设备处于横向模式时,问题就开始了。我用“getResources()。getConfiguration()。orientation”来检查这个。这时我想用另一个版本的布局“list_frag.xml”更改起始片段“ListFrag.java”。因此,我将此布局放在名为“layout-land”的新res文件夹中。此布局定义左窗格的静态片段和右窗格的框架布局。如果用户单击左窗格中的项目,则框架布局用作要加载的细节fragmen的容器。

我真的不知道是否可以使用其中带有静态片段定义的布局来更改活动的内容。我已经尝试了一切但没有任何作用。可能在这里有人有个主意。

以下是项目中单个文件的源代码。为了缩短代码,我删除了import-statements: 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:     package 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):threadid = 1:线程退出,未捕获异常(group = 0x414539a8)   10-11 13:20:12.583:E / AndroidRuntime(5158):致命异常:主要   10-11 13:20:12.583:E / AndroidRuntime(5158):java.lang.IllegalArgumentException:找不到片段ImgFrag {417af140#1 id = 0x7f060041}的id 0x7f060041(com.example.wbslideshow:id / myImgContainer)的视图   10-11 13:20:12.583:E / AndroidRuntime(5158):在android.app.FragmentManagerImpl.moveToState(FragmentManager.java:877)   10-11 13:20:12.583:E / AndroidRuntime(5158):在android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)   10-11 13: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):在android.app.FragmentManagerImpl $ 1.run(FragmentManager.java:441)   10-11 13:20:12.583:E / AndroidRuntime(5158):在android.os.Handler.handleCallback(Handler.java:725)   10-11 13:20:12.583:E / AndroidRuntime(5158):在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):在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):at dalvik.system.NativeStart.main(Native Method)

我可以看到“没有找到......”有问题,但我不知道为什么。对我来说,res / layout-land中的布局文件似乎没有以横向模式加载,因此IMgFrag的onCreateView会出现问题。 但为什么呢?

安德烈亚斯

2 个答案:

答案 0 :(得分:0)

ID myImgContainer在布局layout-land/list_frag.xml中可用,到调用点击事件时,屏幕上只显示main_frag,而不是R.id.myImgContainer MainActivity用户R.id.mycontainer本身。

答案 1 :(得分:0)

您不应在layout-land / list_frag.xml文件中使用fragment标记。

list_frag.xml是ListFrag类的布局。您尝试将ListFrag放入其自己的布局文件中。这是错的。

在横向模式下,您想要一个纵向模式列表下方的Im​​ageView和列表右侧的ImageView(如两个面板)吗?

如果你想这样做。您只需要编写layout-land / 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,因此请将其从layout / 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(); 
}