2015-10-15 70 views
0

我使用ListView与ArrayAdapter并试图添加片段到ListView的所有行。但是,该应用程序无法正常工作:屏幕上仅显示一行,显示添加的片段但不是所有行。有时候,应用程序可能会因为内存不足而崩溃。Android的ArrayAdapter:添加的片段行错误地工作

有人可以给我一些建议吗?谢谢。

MainActivity.java

package com.me.test05; 

import android.app.Activity; 
import android.app.Fragment; 
import android.app.FragmentTransaction; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.TextView; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     if (savedInstanceState == null) { 
      ListView myListView = (ListView) findViewById(R.id.myListView); 
      myListView.setAdapter(new MyArrayAdaptor(this, R.layout.row)); 
     } 
    } 

    public static class PlaceholderFragment extends Fragment { 

     public PlaceholderFragment() { 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      View rootView = inflater.inflate(R.layout.fragment_main, container, false); 
      return rootView; 
     } 
    } 

    private static final String[] allnames = { "John", "Marry", "Smith", "Felicity", "Lion", "Math" }; 

    public static class MyArrayAdaptor extends ArrayAdapter<String> { 
     private final Context context; 

     public MyArrayAdaptor(Context context, int resource) { 
      super(context, resource); 
      this.context = context; 
     } 

     @Override 
     public int getCount() { 
      return allnames.length * 100; 
     } 

     @Override 
     public String getItem(int position) { 
      return allnames[position % allnames.length]; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View rowView = inflater.inflate(R.layout.row, parent, false); 

      TextView textView = (TextView) rowView.findViewById(R.id.textView1); 
      String str = getItem(position); 
      textView.setText(str); 

      FragmentTransaction ft = ((Activity) context).getFragmentManager().beginTransaction(); 
      ft.replace(R.id.myFrameLayout, new PlaceholderFragment()); 
      ft.commit(); 

      return rowView; 
     } 
    } 
} 

文件activity.xml:

<merge xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fitsSystemWindows="true"> 

    <ListView android:id="@+id/myListView" 
     android:layout_height="fill_parent" 
     android:layout_width="fill_parent" 
     android:dividerHeight="2px"> 
    </ListView> 

</merge> 

文件row.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="abc" /> 

    <FrameLayout 
     android:id="@+id/myFrameLayout" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     > 
    </FrameLayout> 

</LinearLayout> 

文件fragment_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" > 

    <Button 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignLeft="@+id/textView1" 
     android:layout_below="@+id/textView1" 
     android:text="Button" /> 

    <TextView 
     android:id="@+id/textView2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/hello_world" /> 


</LinearLayout> 

屏幕看起来像:

+0

为什么你想显示的片段?列表视图应该做什么?我认为你做得比应该更难。 –

+0

仅用于处理复杂性:在接下来的步骤中,我添加的片段可能更复杂,可能是10个不同的片段。另外,不仅每行可以添加一个但少量的片段 – Tony

回答

0

我已经解决了这个问题。问题是片段管理器总是在全局中查找(用新片段替换)一个id。这就是为什么它总是找到并添加所有新的片段到第一行,因为它是第一个包含该ID(以及所有其他行)。

为了解决这个问题,我创建了每行都是唯一的动态标识符,然后在让片段管理器完成剩下的工作之前,用它们替换固定的标识符。我还将这些动态ID存储到行标记中以重复使用后者。

新的代码是波纹管,其中包括寻找和重用添加片段代码:

package com.me.test05; 

import android.app.Activity; 
import android.app.Fragment; 
import android.app.FragmentTransaction; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.FrameLayout; 
import android.widget.ListView; 
import android.widget.TextView; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     if (savedInstanceState == null) { 
      ListView myListView = (ListView) findViewById(R.id.myListView); 
      myListView.setAdapter(new MyArrayAdaptor(this, R.layout.row)); 
     } 
    } 

    public static class PlaceholderFragment extends Fragment { 
     private View rootView = null; 
     private String theString = null; 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      rootView = inflater.inflate(R.layout.fragment_main, container, false); 
      setString(theString); 

      return rootView; 
     } 

     public void setString(String str) { 
      theString = str; 
      if (theString != null && rootView != null) { 
       TextView textView = (TextView) rootView.findViewById(R.id.textView2); 
       textView.setText(str); 
      } 
     } 
    } 

    private static final String[] allnames = { "John", "Marry", "Smith", "Felicity", "Lion", "Math" }; 

    public static class MyArrayAdaptor extends ArrayAdapter<String> { 
     private final Context context; 

     public MyArrayAdaptor(Context context, int resource) { 
      super(context, resource); 
      this.context = context; 
     } 

     @Override 
     public int getCount() { 
      return allnames.length * 100; 
     } 

     @Override 
     public String getItem(int position) { 
      return allnames[position % allnames.length]; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View rowView = convertView; 

      PlaceholderFragment myFragment = null; 
      if (rowView == null) { 
       rowView = inflater.inflate(R.layout.row, parent, false); 

       int newId = 100000 + position; 
       FrameLayout layout = (FrameLayout) rowView.findViewById(R.id.myFrameLayout); 
       layout.setId(newId); 
       rowView.setTag(newId); 

       myFragment = new PlaceholderFragment(); 
       FragmentTransaction ft = ((Activity) context).getFragmentManager().beginTransaction(); 
       ft.replace(newId, myFragment, "" + newId).commit(); 
      } else { 
       Integer theId = (Integer) convertView.getTag(); 
       myFragment = (PlaceholderFragment) ((Activity) context).getFragmentManager().findFragmentById(theId); 
      } 
      String str = getItem(position); 
      myFragment.setString(str + ", " + position); 

      TextView textView = (TextView) rowView.findViewById(R.id.textView1); 
      textView.setText(str); 

      return rowView; 
     } 
    } 
}