0

ActionBarFragmentインターフェイスを実装するこのアプリケーションがあります。インターフェイスの基礎には、別のタブに切り替えるたびにリスト内のエントリが複製され続けるListFragmentが1つあります。カスタムアダプタを使用してリストフラグメントを実装する正しい方法を誰かに教えてもらえますか?

以下は私のコードです:FeaturedFragment.java

public class FeaturedFragment extends ListFragment {

static final String URL = "http://www.sundancepost.com/ivue/Featured.xml";

static final String KEY_PROJECT = "project"; // parent node
static final String KEY_BANNER = "banner";

ListView featuredList;
FeaturedListAdapter featuredAdapter;
ArrayList<HashMap<String, String>> projectsList = new ArrayList<HashMap<String, String>>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.featured_list, container, false);
        featuredList = (ListView)view.findViewById(android.R.id.list);

        return view;
 }

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

        ConnectivityManager cMgr = (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
         if (cMgr.getActiveNetworkInfo() != null && cMgr.getActiveNetworkInfo().isConnectedOrConnecting()) {

            new MyAsyncTask().execute();

          } else {
             AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
             builder.setMessage("Please check your internet connection");
             builder.setTitle("Failed to download resources");
             builder.setCancelable(false);
             builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                           return;
                       }
                   });
                AlertDialog alert = builder.create();
                alert.show();
        }

    featuredAdapter = new FeaturedListAdapter(getActivity(), projectsList);

}

public class MyAsyncTask extends AsyncTask<Void,Void,Void>{

    private final ProgressDialog recents_dialog = new ProgressDialog(getActivity());

    @Override
    protected Void doInBackground(Void... params) {

        XMLParser parser = new XMLParser();
        String xml = parser.getXmlFromUrl(URL);
        Document doc = parser.getDomElement(xml);

        NodeList nl = doc.getElementsByTagName(KEY_PROJECT);

        for (int i = 0; i < nl.getLength(); i++) {

            HashMap<String, String> map = new HashMap<String, String>();
            Element e = (Element) nl.item(i);

            map.put(KEY_BANNER, parser.getValue(e, KEY_BANNER));

            projectsList.add(map);
        }
        return null;
    }

    @Override
    protected void onPreExecute()
    {
        recents_dialog.setMessage("Loading ...");
        recents_dialog.show();
        recents_dialog.setCancelable(false);
    }

    @Override
    protected void onPostExecute(Void result)
    {
        if(recents_dialog.isShowing() == true)
        {
            recents_dialog.dismiss();
        }
         // Getting adapter by passing xml data ArrayList

        featuredList.setAdapter(featuredAdapter);

    }
  }

}

FeaturesListAdapter:

public class FeaturedListAdapter extends BaseAdapter {

private Activity activity;
ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader; 

public FeaturedListAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
    activity = a;
    data= (ArrayList<HashMap<String, String>>) d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    imageLoader=new ImageLoader(activity.getApplicationContext());
}

public int getCount() {
    return data.size();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {

        View vi = convertView;

        if(vi==null){
            vi=new View(activity);
            vi = inflater.inflate(R.layout.featured_listrow, null);
        }

        ImageView banner =(ImageView)vi.findViewById(R.id.banner); // thumb image
        banner.setAdjustViewBounds(true);
        imageLoader.DisplayImage(data.get(position).get(FeaturedFragment.KEY_BANNER), banner);

        return vi;
  }
}

[編集]次のコードは@10sの提案に基づいて変更されています。しかし、結果は同じです。

public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.featured_listrow, null);
            holder = new ViewHolder();
            holder.banner = (ImageView)convertView.findViewById(R.id.banner);
            holder.banner.setAdjustViewBounds(true);
            imageLoader.DisplayImage(data.get(position).get(FeaturedFragment.KEY_BANNER), holder.banner);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }
        return convertView;
}

public static class ViewHolder {
    public ImageView banner;
}
4

2 に答える 2

1

カスタムアダプタのgetView()で使用しているコードは、呼び出されるたびにビューを再作成しています。また、アダプターはアクティビティのたびに再レンダリングします。この場合、フラグメントがフォーカスされます。

アダプターにホルダーを使用してみてください。これはAndroidのベストプラクティスであり、非常に簡単で便利なものです。開始するためのリンク:http ://android.amberfog.com/?p = 296

于 2012-07-03T07:31:28.793 に答える
0

タブを切り替えるたびに重複エントリを追加する理由は、このタブに切り替えるたびにonActivityCreated()メソッドがnごとに呼び出されるためです。したがって、AsyncTaskは毎回実行され、AsyncTaskのdoInBackground()メソッドでは、要素をクリアせずにprojectListarraylistに追加し続けました。

asyncTaskを開始する前にprojectListをクリアするか、リストにデータが含まれているかどうかを確認し、それに基づいてasyncTaskを実行するように呼び出します(リストがnullであるか、要素が含まれていない場合)。

于 2012-07-03T09:24:05.970 に答える