我有一个在开始时使用活动的应用。它正在加载一个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会出现问题。 但为什么呢?
安德烈亚斯
答案 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放入其自己的布局文件中。这是错的。
在横向模式下,您想要一个纵向模式列表下方的ImageView和列表右侧的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();
}