提高Custom ArrayAdapters和Objects的性能

时间:2015-04-10 19:09:57

标签: android performance object android-arrayadapter

我一直在尝试使用this tutorial了解如何在我的某些Android应用中使用自定义ArrayAdapter,但稍微调整一下以便我可以使用自己的应用程序。

我现在已经在手机上测试了几次,但我发现性能速度非常慢(加载和滚动列表视图时)。不使用此自定义ArrayAdapter的其他活动具有正常的性能速度。

我不确定问题是什么,或者我的代码会在哪里,所以下面,我发布了所有自定义ArrayAdapter类:

package com.mycompany.myapp;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomArrayAdapter extends ArrayAdapter<String> {

    private static class ViewHolder {
        TextView tv_Id;
        TextView tv_Name;
        TextView tv_Group;
    }

    private Context context;
    private ArrayList<String> arr_items;

    public CustomArrayAdapter(Context context, ArrayList<String> arr_items) {
        super(context, R.layout.listview_advanced, arr_items);
        this.context = context;
        this.arr_items = arr_items;
    }

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

        // Get the data item for this position
        Person person = new Person(context, arr_items.get(position));

        // Check if an existing view is being reused, otherwise inflate the view
        ViewHolder viewHolder; // View lookup cache stored in tag
        if (convertView == null) {
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.listview_advanced, parent, false);
            viewHolder.tv_Id = (TextView) convertView.findViewById(R.id.lvAdv_text1);
            viewHolder.tv_Name = (TextView) convertView.findViewById(R.id.lvAdv_text2);
            viewHolder.tv_Group = (TextView) convertView.findViewById(R.id.lvAdv_text3);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        // Populate the data into the template view using the data object
        viewHolder.tv_Id.setText(person.getIDAsString());
        viewHolder.tv_Name.setText(person.getName());
        if (person.getGroup().equals("")) {
            viewHolder.tv_Group.setText("");
        } else {
            viewHolder.tv_Group.setText("(" + person.getGroup() + ")");
        }

        // Return the completed view to render on screen
        return convertView;
    }
}

非常感谢任何帮助。感谢。

更新:

此外,在调用CustomArrayAdapter之前,我通过遍历ArrayList<String>文件的行并获取该数据,将数据添加到.csv。目前,在阅读.csv文件时,我有这个:

...

ArrayList<String> arr_person = new ArrayList<>(); // Global variable

...

// In a method:
String data = inputStream.nextLine();
String[] line = data.split(",");
if (line.length >1) {
    arr_person.add(line[1]);
}

...

CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(), arr_person);
lv_main.setAdapter(adapter);

我如何针对对象进行调整?

更新2:

我的Person对象的工作原理如下:

private Context context;
private String person, group, someAttribute, ... ;
private int idNumber, scoreOne, scoreTwo, scoreThree, scoreFour, scoreFive, scoreSix, scoreTotal, ... ;
private double ... ;

public Person(Context context, String person) {
    this.context = context;
    this.person = person;

    loadInformation();
}

private void loadInformation() {
    InputStreamReader inputStreamReader;
    try {
        inputStreamReader = new InputStreamReader(context.getAssets().open("PersonsList.csv"));
        Scanner inputStream = new Scanner(inputStreamReader);
        inputStream.nextLine(); // Ignores the first line
        while (inputStream.hasNext()) {
            String data = inputStream.nextLine(); // Gets a whole line
            String[] line = data.split(","); // Splits the line up into a string array

            if (line.length > 1) {
                if (line[1].equals(person)) {
                    idNumber = Integer.parseInt(line[0]);
                    person = line[1];
                    group = line[2];

                    someAttribute = line[3];

                    scoreOne = Integer.parseInt(line[4]);
                    scoreTwo = Integer.parseInt(line[5]);
                    scoreThree = Integer.parseInt(line[6]);
                    scoreFour= Integer.parseInt(line[7]);
                    scoreFive = Integer.parseInt(line[8]);
                    scoreSix = Integer.parseInt(line[9]);
                    scoreTotal = scoreOne + scoreTwo + scoreThree + scoreFour + scoreFive + scoreSix;

                    // Same code pattern for defining about 10 more attributes
                }
            }
        }
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public int getID() {
    return idNumber;
}

public String getIDAsString() {
    return format(idNumber);
}

private String format(int number) {
    String str_num = String.valueOf(number);
    switch (str_num.length()) {
        case 1:
            str_num = "00" + str_num;
            break;
        case 2:
            str_num = "0" + str_num;
            break;
        case 3:
            // Leave it how it is;
            break;
    }
    return str_num;
}

public String getName() {
    return person;
}

public String getGroup() {
    return group;
}

public String getSomeAttribute() {
    return someAttribute;
}

public int getScoreOne() {
    return scoreOne;
}

public int getScoreTwo() {
    return scoreTwo;
}

...

1 个答案:

答案 0 :(得分:2)

将数组和ArrayAdapter基于Person而不是String,并在设置适配器之前列出Person s 。这样,您只需运行一次Person构造函数,而不是每次显示其视图。

ArrayList<Person> arr_person = new ArrayList<>();  // Global variable

... 

String data = inputStream.nextLine();
String[] line = data.split(",");
if (line.length > 1) {
    Person person = new Person(context, line[1]);
    arr_person.add(person); 
} 

... 

CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(), arr_person); 
lv_main.setAdapter(adapter);

... 

package com.mycompany.myapp;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;

public class CustomArrayAdapter extends ArrayAdapter<Person> {

    private static class ViewHolder {
        TextView tv_Id;
        TextView tv_Name;
        TextView tv_Group;
    }

    private Context context;
    private ArrayList<Person> persons;

    public CustomArrayAdapter(Context context, ArrayList<Person> persons) {
        super(context, R.layout.listview_advanced, arr_items);
        this.context = context;
        this.persons = persons;
    }

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

        // Get the data item for this position
        Person person = persons.get(position);

        // Check if an existing view is being reused, otherwise inflate the view
        ViewHolder viewHolder; // View lookup cache stored in tag
        if (convertView == null) {
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.listview_advanced, parent, false);
            viewHolder.tv_Id = (TextView) convertView.findViewById(R.id.lvAdv_text1);
            viewHolder.tv_Name = (TextView) convertView.findViewById(R.id.lvAdv_text2);
            viewHolder.tv_Group = (TextView) convertView.findViewById(R.id.lvAdv_text3);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        // Populate the data into the template view using the data object
        viewHolder.tv_Id.setText(person.getIDAsString());
        viewHolder.tv_Name.setText(person.getName());
        if (person.getGroup().equals("")) {
            viewHolder.tv_Group.setText("");
        } else {
            viewHolder.tv_Group.setText("(" + person.getGroup() + ")");
        }

        // Return the completed view to render on screen
        return convertView;
    }
}