从我可以收集的内容看来,这可能是因为我的ListView没有显示,我已经验证了getCount返回的值不是零,但我看不出我做错了什么。
所有东西都加载并且像它一样工作,但ListView永远不会出现,我在mixed.xml中的片段引用上加了一个背景颜色,它就在那里并占据了整个屏幕,但当我在ListView上设置背景颜色时它没有出现,就像它根本没有渲染一样。
更奇怪的是,我的适配器中没有调用getView,这是我移植到片段的常规活动的所有工作代码。
我尝试过调用notifyDataSetChanged,它没有改变任何东西,调试显示适配器充满了数据,而getCount确实返回了大于0的准确计数。
感谢您的帮助,我被困住了。
项目已开放,可在此处http://code.google.com/p/shack-droid/source/browse/#svn%2FTrunk查看,但我也在此处提供相关代码。
这是ListFragment:
public class FragmentTopicView extends ListFragment implements ShackGestureEvent {
private ArrayList<ShackPost> posts;
private String storyID = null;
private String errorText = "";
private Integer currentPage = 1;
private Integer storyPages = 1;
private String loadStoryID = null;
private Boolean threadLoaded = true;
private Hashtable<String, String> postCounts = null;
private AdapterLimerifficTopic tva;
public FragmentTopicView() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.topics, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final ShackGestureListener listener = Helper.setGestureEnabledContentView(R.layout.topics, getActivity());
if (listener != null) {
listener.addListener(this);
}
if (savedInstanceState == null) {
// get the list of topics
GetChattyAsyncTask chatty = new GetChattyAsyncTask(getActivity());
chatty.execute();
}
ListView lv = getListView();
lv.setOnScrollListener(new OnScrollListener() {
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// start loading the next page
if (threadLoaded && firstVisibleItem + visibleItemCount >= totalItemCount && currentPage + 1 <= storyPages) {
// get the list of topics
currentPage++;
GetChattyAsyncTask chatty = new GetChattyAsyncTask(getActivity());
chatty.execute();
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
});
}
class GetChattyAsyncTask extends AsyncTask<String, Void, Void> {
protected ProgressDialog dialog;
protected Context c;
public GetChattyAsyncTask(Context context) {
this.c = context;
}
@Override
protected Void doInBackground(String... params) {
threadLoaded = false;
try {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
final String feedURL = prefs.getString("shackFeedURL", getString(R.string.default_api));
final URL url;
if (loadStoryID != null) {
if (currentPage > 1)
url = new URL(feedURL + "/" + loadStoryID + "." + currentPage.toString() + ".xml");
else
url = new URL(feedURL + "/" + loadStoryID + ".xml");
}
else {
if (currentPage > 1)
url = new URL(feedURL + "/" + storyID + "." + currentPage.toString() + ".xml");
else
url = new URL(feedURL + "/index.xml");
}
// Get a SAXParser from the SAXPArserFactory.
final SAXParserFactory spf = SAXParserFactory.newInstance();
final SAXParser sp = spf.newSAXParser();
// Get the XMLReader of the SAXParser we created.
final XMLReader xr = sp.getXMLReader();
// Create a new ContentHandler and apply it to the XML-Reader
SaxHandlerTopicView saxHandler = new SaxHandlerTopicView(c, "topic");
xr.setContentHandler(saxHandler);
// Parse the xml-data from our URL.
xr.parse(new InputSource(HttpHelper.HttpRequestWithGzip(url.toString(), c)));
// Our ExampleHandler now provides the parsed data to us.
if (posts == null) {
posts = saxHandler.GetParsedPosts();
}
else {
ArrayList<ShackPost> newPosts = saxHandler.GetParsedPosts();
newPosts.removeAll(posts);
posts.addAll(posts.size(), newPosts);
}
storyID = saxHandler.getStoryID();
storyPages = saxHandler.getStoryPageCount();
if (storyPages == 0) // XML returns a 0 for stories with only
// one page
storyPages = 1;
}
catch (Exception ex) {
// TODO: implement error handling
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (currentPage == 1)
dialog = ProgressDialog.show(getActivity(), null, "Loading Chatty", true, true);
else
SetLoaderVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
ShowData();
SetLoaderVisibility(View.GONE);
try {
dialog.dismiss();
}
catch (Exception e) {
}
}
}
private void ShowData() {
if (posts != null) {
Hashtable<String, String> tempHash = null;
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
final String login = prefs.getString("shackLogin", "");
final int fontSize = Integer.parseInt(prefs.getString("fontSize", "12"));
try {
postCounts = GetPostCache();
}
catch (Exception ex) {
}
if (postCounts != null)
tempHash = new Hashtable<String, String>(postCounts);
if (tva == null) {
tva = new AdapterLimerifficTopic(getActivity(), R.layout.lime_topic_row, posts, login, fontSize, tempHash);
setListAdapter(tva);
}
else {
tva.SetPosts(posts);
tva.notifyDataSetChanged();
}
final ListView lv = getListView();
lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Options");
menu.add(0, 1, 0, "Copy Post Url to Clipboard");
menu.add(0, 2, 0, "Watch Thread");
menu.add(0, 3, 0, "Thread Expires In?");
menu.add(0, 4, 0, "Shacker's Chatty Profile");
}
});
// update the reply counts for the listing of topics
try {
UpdatePostCache();
}
catch (Exception e) {
}
}
else {
if (errorText.length() > 0) {
try {
new AlertDialog.Builder(getActivity()).setTitle("Error").setPositiveButton("OK", null).setMessage(errorText).show();
}
catch (Exception ex) {
// could not create a alert for the error for one reason
// or another
Log.e("ShackDroid", "Unable to create error alert ActivityTopicView:468");
}
}
}
threadLoaded = true;
}
}
这是我的FragmentActivity:
public class FragmentActivityTopic extends FragmentActivity {
@Override
protected void onCreate(Bundle arg) {
// TODO Auto-generated method stub
super.onCreate(arg);
setContentView(R.layout.mixed);
}
}
这是我正在使用的适配器,如上所述,getView未被调用:
public class AdapterLimerifficTopic extends BaseAdapter {
// private Context context;
private List<ShackPost> topicList;
private final int rowResouceID;
private final String shackLogin;
private final Typeface face;
private final int fontSize;
private final Hashtable<String, String> postCache;
private final String showAuthor;
private final Resources r;
private int totalNewPosts = 0;
LayoutInflater inflate;// = LayoutInflater.from(context);
public AdapterLimerifficTopic(Context context, int rowResouceID, List<ShackPost> topicList, String shackLogin, int fontSize, Hashtable<String, String> postCache) {
this.topicList = topicList;
this.rowResouceID = rowResouceID;
this.shackLogin = shackLogin;
this.fontSize = fontSize;
this.postCache = postCache;
this.r = context.getResources();
face = Typeface.createFromAsset(context.getAssets(), "fonts/arial.ttf");
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
showAuthor = prefs.getString("showAuthor", "count");
inflate = LayoutInflater.from(context);
}
public void SetPosts(List<ShackPost> posts)
{
topicList = posts;
}
@Override
public int getCount() {
return topicList.size();
}
@Override
public Object getItem(int position) {
return topicList.get(position);
}
@Override
public long getItemId(int position) {
// return position;
final ShackPost post = topicList.get(position);
return Long.parseLong(post.getPostID());
}
static class ViewHolder {
TextView posterName;
TextView datePosted;
TextView replyCount;
TextView newPosts;
TextView postText;
TextView viewCat;
RelativeLayout topicRow;
ImageView postTimer;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TextView tmp;
// final View v;
ViewHolder holder;
final ShackPost post = topicList.get(position);
if (convertView == null) {
convertView = inflate.inflate(rowResouceID, parent, false);
holder = new ViewHolder();
holder.posterName = (TextView) convertView.findViewById(R.id.TextViewLimeAuthor);
holder.datePosted = (TextView) convertView.findViewById(R.id.TextViewLimePostDate);
holder.replyCount = (TextView) convertView.findViewById(R.id.TextViewLimePosts);
holder.newPosts = (TextView) convertView.findViewById(R.id.TextViewLimeNewPosts);
holder.postText = (TextView) convertView.findViewById(R.id.TextViewLimePostText);
holder.viewCat = (TextView) convertView.findViewById(R.id.TextViewLimeModTag);
// holder.topicRow = (RelativeLayout) convertView.findViewById(R.id.TopicRow);
// holder.postTimer = (ImageView) convertView.findViewById(R.id.ImageViewTopicTimer);
// holder.posterName.setTypeface(face);
// holder.datePosted.setTypeface(face);
// holder.replyCount.setTypeface(face);
// holder.newPosts.setTypeface(face);
holder.postText.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
// holder.postText.setTypeface(face);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
// holder.postTimer.setImageResource(Helper.GetTimeLeftDrawable(post.getPostDate()));
//
holder.posterName.setText(post.getPosterName());
//
// if (shackLogin.equalsIgnoreCase(post.getPosterName()))
// holder.posterName.setTextColor(Color.parseColor("#00BFF3"));
// else
// holder.posterName.setTextColor(Color.parseColor("#ffba00"));
//
holder.datePosted.setText(Helper.FormatShackDateToTimePassed(post.getPostDate()));
holder.replyCount.setText(post.getReplyCount());
//
// if (showAuthor.equalsIgnoreCase("count") && post.getIsAuthorInThread())
// holder.replyCount.setTextColor(Color.parseColor("#0099CC"));
// else
// holder.replyCount.setTextColor(Color.parseColor("#FFFFFF"));
// clipped code
holder.postText.setText(preview);
// if (showAuthor.equalsIgnoreCase("topic") && post.getIsAuthorInThread()) {
// final Drawable d = r.getDrawable(R.drawable.background_gradient_blue);
// holder.topicRow.setBackgroundDrawable(d);
// }
// else
// holder.topicRow.setBackgroundDrawable(null);
// TODO: clean this up a little / also replicated in ShackDroidThread ick
final String postCat = post.getPostCategory();
holder.viewCat.setVisibility(View.VISIBLE);
if (postCat.equals("offtopic")) {
holder.viewCat.setText("offtopic");
holder.viewCat.setBackgroundColor(Color.parseColor("#444444"));
}
else if (postCat.equals("nws")) {
holder.viewCat.setText("nws");
holder.viewCat.setBackgroundColor(Color.parseColor("#CC0000"));
}
else if (postCat.equals("political")) {
holder.viewCat.setText("political");
holder.viewCat.setBackgroundColor(Color.parseColor("#FF8800"));
}
else if (postCat.equals("stupid")) {
holder.viewCat.setText("stupid");
holder.viewCat.setBackgroundColor(Color.parseColor("#669900"));
}
else if (postCat.equals("informative")) {
holder.viewCat.setText("interesting");
holder.viewCat.setBackgroundColor(Color.parseColor("#0099CC"));
}
else
holder.viewCat.setVisibility(View.GONE);
return convertView;
}
public int getTotalNewPosts() {
return totalNewPosts;
}
}
相关的XML:
mixed.xml(这是片段的布局,现在只有一个)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:id="@+id/LinearLayoutMixed">
<fragment
android:id="@+id/MixedThreads"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.stonedonkey.shackdroid.FragmentTopicView"
>
</fragment>
</LinearLayout>
Topics.xml(包含ListView以及滑动托盘和其他一些东西。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/TopicLoader"
android:divider="#333333"
android:dividerHeight="1dip"
android:textColor="#FFFFFF"
/>
<RelativeLayout
android:id="@+id/TopicLoader"
android:layout_width="fill_parent"
android:layout_height="35dip"
android:layout_alignParentBottom="true"
android:gravity="center_horizontal"
android:visibility="gone"
android:layout_marginTop="5dip" >
<TextView
android:id="@+id/TextViewTopicLoaderText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Loading"
>
</TextView>
<ImageView
android:id="@+id/ImageViewTopicLoader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/TextViewTopicLoaderText"
android:src="@drawable/ic_action_refresh"
android:layout_alignBottom="@+id/TextViewTopicLoaderText"
/>
</RelativeLayout>
<SlidingDrawer
android:id="@+id/SlidingDrawer01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@+id/TopicLoader"
android:animateOnClick="true"
android:content="@+id/bookMarkParent"
android:handle="@+id/TextViewTrayHandle"
android:orientation="vertical"
android:paddingTop="200dip"
android:visibility="gone" >
<TextView
android:id="@+id/TextViewTrayHandle"
android:layout_width="fill_parent"
android:layout_height="35dip"
android:background="@drawable/darkgrey_gradient"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center_vertical" >
</TextView>
<RelativeLayout
android:id="@id/bookMarkParent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ListView
android:id="@+id/ListViewWatchedThreads"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#333333"
android:dividerHeight="1dip"
android:textColor="#FFFFFF" >
</ListView>
</RelativeLayout>
</SlidingDrawer>
</RelativeLayout>
最后是lime_topic_row,它是上面布局中ListView的自定义行布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FF0000" >
<TextView
android:id="@+id/TextViewLimeModTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF0000"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dip"
android:textColor="#000000"
android:padding="2dip"
android:textSize="10dip"
/>
<TextView
android:id="@+id/TextViewLimePostText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="20dip"
android:padding="10dip"
android:layout_below="@+id/TextViewLimeModTag"
android:textColor="#FFFFFF" />
<TextView
android:id="@+id/TextViewLimeAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/TextViewLimePostText"
android:paddingBottom="10dip"
android:paddingLeft="10dip"
android:textColor="#0099CC" />
<TextView
android:id="@+id/TextViewPosted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/TextViewLimePostText"
android:layout_toRightOf="@+id/TextViewLimeAuthor"
android:paddingBottom="10dip"
android:text=" posted " />
<TextView
android:id="@+id/TextViewLimePostDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/TextViewLimePostText"
android:layout_toRightOf="@+id/TextViewPosted"
android:paddingBottom="10dip"
android:paddingRight="10dip"
android:textColor="#FF8800" />
<TextView
android:id="@+id/TextViewLimePosts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/TextViewLimePostDate"
android:layout_marginRight="3dip"
android:layout_below="@+id/TextViewLimePostText"
android:layout_marginBottom="15dip"
android:layout_toLeftOf="@+id/TextViewLimeNewPosts"
android:background="#BBBBBB"
android:padding="3dip"
android:minWidth="25dip"
android:gravity="center"
android:textColor="#000000" />
<TextView
android:id="@+id/TextViewLimeNewPosts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/TextViewLimePostDate"
android:layout_below="@+id/TextViewLimePostText"
android:layout_marginBottom="15dip"
android:layout_marginRight="10dip"
android:background="#669900"
android:padding="3dip"
android:minWidth="25dip"
android:gravity="center"
android:layout_alignParentRight="true"
android:textColor="#000000" />
</RelativeLayout>
答案 0 :(得分:1)
我想我发现了这个问题。出现此问题的原因是您在ShackGestureListener
的{{1}}方法开头设置了onActivityCreated
:
FragmentTopicView
在final ShackGestureListener listener = Helper.setGestureEnabledContentView(R.layout.topics, getActivity());
if (listener != null) {
listener.addListener(this);
}
方法中,您检查用户是否在首选项中启用了手势,或者Android版本是否大于3.无论哪种方式,setGestureEnabledContentView()
或true
您设置false
的内容视图(包含FragmentActivityTopic
的布局)。不幸的是,再次设置内容视图将覆盖当前布局,该布局保存FragmentTopicView
数据(ListView
,填充没有问题)。当您运行这些ListView
来获取数据时,最后您将数据设置为正确的AsyncTasks
(由ListView
返回),因为getListView
将保留对getListView
的引用在ListView
方法中设置的旧的正确onCreateView
,但您没有看到任何内容,因为在setGestureEnabledContentView
中您覆盖了这个ListView
。
如果您简单地注释掉(或删除)为Helper
和HelperAPI4
类中的活动设置内容视图的行,则很容易看到此行为。另一种查看ListView
被覆盖的方法是,例如使用ListView
为getListView
( tva )设置适配器并使用{{1 (我已经选择了你的一个菜单项,所以我可以控制何时更换适配器):
getActivity().findViewById(android.R.id.list)
我不知道推荐什么作为解决方案,因为我不太明白你在做什么,但我怀疑它需要再次设置活动的内容视图(你应该从这里工作)