我的Android应用程序存在两个问题。我将从相关代码开始,我肯定99%已锁定在我的MainActivity类中:
package com.simplerssreader;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class MainActivity extends FragmentActivity {
private ListView list;
private TextFragment text;
private RssFragment rss;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Initializing AddNote fragment
if (getFragmentManager().findFragmentByTag("RSS") == null)
{
rss = new RssFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, rss, "RSS").commit();
}
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
if (getFragmentManager().findFragmentByTag("RSS") == null)
{
rss = new RssFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, rss, "RSS").commit();
}
if (getFragmentManager().findFragmentByTag("TEXT") == null)
{
text = new TextFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.text, text, "TEXT").commit();
}
}
//View view = getLayoutInflater().inflate(R.layout.fragment_layout, null);
list = (ListView) this.findViewById(R.id.listView);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
System.out.println("YES!");
/*RssAdapter adapter = (RssAdapter) parent.getAdapter();
RssItem item = (RssItem) adapter.getItem(position);
TextFragment fragment = new TextFragment();
fragment.setLink(item.getLink());
FragmentManager fragMgr = getSupportFragmentManager();
FragmentTransaction xact = fragMgr.beginTransaction();
xact.replace(R.id.text, fragment, "TEXT");*/
}
});
if (savedInstanceState != null) {
text = (TextFragment) getSupportFragmentManager().findFragmentByTag("TEXT");
rss = (RssFragment) getSupportFragmentManager().findFragmentByTag("RSS");
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("fragment_added", true);
}
}
(请注意,我现在并不关心onItemSelected中的代码;当我实际使用代码时,我将在稍后处理它。)
所以我的第一个问题是这一行:
list = (ListView) this.findViewById(R.id.listView);
我希望在这里获得的是在当前显示中找到的ListView(在纵向或横向模式下,将显示列表视图)。我也在上面注释掉的行中尝试了另一种方法,但它也失败了。这里的错误是NullPointerException。
我的第二个问题是每当我从横向模式进入纵向模式时,应用程序崩溃。我可以从纵向到横向,并以任一模式启动,但回到肖像会杀死应用程序。我已经对onCreate的方向进行了适当的检查,所以我不确定我哪里出错了。这里的错误表明在当前视图中没有要查找的TextView,但只有当我在横向模式下才能调用它,对吗?
无论如何,非常感谢任何帮助!
以下是我的布局:
fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
main.xml(肖像)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:id="@+id/fragment_container"
android:layout_height="fill_parent"
/>
text_view.xml
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
main.xml(landscape)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent" android:layout_height="match_parent"
android:baselineAligned="false">
<FrameLayout android:id="@+id/fragment_container" android:layout_weight="1"
android:layout_width="0px" android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" />
<FrameLayout android:id="@+id/text" android:layout_weight="2"
android:layout_width="0px" android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" />
</LinearLayout>
答案 0 :(得分:0)
首先,尝试将获取列表视图的代码移动到片段。
另外,
if (savedInstanceState != null) {
text = (TextFragment) getSupportFragmentManager().findFragmentByTag("TEXT");
rss = (RssFragment) getSupportFragmentManager().findFragmentByTag("RSS");
}
如果以前没有TEXT片段,你会覆盖text
,以防savedInstance
最后,您有重复的ID:
<FrameLayout android:id="@+id/text" android:layout_weight="2"
android:layout_width="0px" android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" />
和
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
答案 1 :(得分:0)
首先,我在您的活动中看不到您的ListView
设置为Adapter
。这只是一个简单的示例,其中customtextview
是一个简单的TextView
和items
一个字符串数组:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.customtextview, items);
listView.setAdapter(adapter);
然后,您有两个带有“text”(R.layout.text_view
和R.layout.main
风景中的FrameLayout)的ID。如果你在其中一个片段中使用它们,这将会崩溃。改变其中一个..
并且,因为您只在横向模式下拥有FrameLayout
“文本”,所以您可以按照以下执行onCreate方法(检查此FrameLayout是否存在):
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// in both layout, you add this Fragment in the same FrameLayout
// check the savedInstanceState, if isn't null = orientation has changed
if (savedInstanceState == null)
rss = new RssFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, rss, "RSS").commit();
} else {
rss = (RssFragment) getSupportFragmentManager().findFragmentByTag("RSS");
}
/*
** check if FrameLayout text is null (true = landscape)
*/
if(findViewById(R.id.text) != null) {
// check the savedInstanceState
if (savedInstanceState == null) {
text = new TextFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.text, text, "TEXT").commit();
} else {
text = (TextFragment) getSupportFragmentManager().findFragmentByTag("TEXT");
}
}
/*
** else the id isn't exist (false = portrait) // do nothing
*/
}
然后,在RSS Fragment
中,设置ListView
:
private ListView list;
String[] items = new String[] {
"One",
"Two",
"Three",
"And so on.."
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_layout, container, false);
list = (ListView) v.findViewById(R.id.listView);
ArrayAdapter<String> adapt = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
list.setAdapter(adapt);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
System.out.println("YES!");
/* some stuff */
}
});
return v;
}
要在活动中保存片段状态,您可以使用setRetainInstance(true)
。它上面有一个great post和一个tutorial。有关片段和方向发生变化的更多信息,请阅读this answer。
如果这有用,请告诉我。
我在网上搜索了一下,我发现这些教程可能对你有很大帮助:
所有内容均适用于WebView
,并且主要使用findFragmentById
而非tag
。也许这是线索..
但是你可以直接在xml上添加适当的片段,如:
- Portrait Mode :
o layout 1 : listview (ex fragment RSS)
o layout 2 : fragment WebView
- Landscape Mode :
o layout 1 :
LinearLayout (id container) : listview (ex fragment RSS) + framelayout
在您的FragmentActivity
上,您托管列表并检查方向,如下所示:
ListView list = (ListView) findViewById(...);
list.setAdapter(...);
LinearLayout container = (LinearLayout) findViewById(R.id.container);
if(container != null) {
// your framelayout is present so set your fragment WebView
// inside it with a fragment transaction and also
// use the item clicked to send info to this fragment
} else {
// call a new activity on item clicked to display the WebView
}
这应该有效。
我希望这些添加的信息可以帮助您实现这一目标。