2015-10-15 72 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; 
     } 
    } 
}