android - 如何将 AsyncTask 与 ListView 适配器一起使用

标签 android listview android-asynctask android-adapter getview

所以,我有一个 ListView,我正在我的 TodayFragment 上显示它。有 TodayTaskAdapter,可自定义此列表。当actvity正在加载时,由于列表的原因,它需要花费很多时间。并减慢应用程序。问题是:

我应该如何正确使用AsyncTask?什么是正确使用它的地方:

  1. 在 fragment 中,设置适配器时;
  2. 在适配器的 getView() 方法中进行操作 背景;
  3. 还是其他地方?

我还不是很喜欢。需要帮助。

今日 fragment

public class TodayFragment extends AbstractTabFragment
{
    public static final String TODAY_PAGE = "TODAY_PAGE";
    private static final int LAYOUT = R.layout.fragment_today;

    private ListView task_list;

    private TodayTaskAdapter today_task_adapter;

    private Event event;
    private Event event1;
    private Event event3;

    private Event event4;
    private Event event5;

    private Event event6;
    private Event event7;

    private Event event8;
    private Event event9;

    public static TodayFragment newInstance(int page, Context context)
    {
        Bundle args = new Bundle();
        args.putInt(TODAY_PAGE, page);

        TodayFragment fragment = new TodayFragment();
        fragment.setArguments(args);
        fragment.setContext(context);
        fragment.setTitle(context.getString(R.string.tab_today_name));

        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        view = inflater.inflate(LAYOUT, container, false);

        task_list = (ListView) view.findViewById(R.id.tasks_list);

        today_task_adapter = new TodayTaskAdapter(getActivity(), R.layout.today_list_item);

        eventCreation();

        today_task_adapter.add(new EventTypeSection("Schedule"));
        today_task_adapter.add(event);
        today_task_adapter.add(event1);
        today_task_adapter.add(event3);

        today_task_adapter.add(new EventTypeSection("ToDo"));
        today_task_adapter.add(event4);
        today_task_adapter.add(event5);

        today_task_adapter.add(new EventTypeSection("Work Task"));
        today_task_adapter.add(event6);
        today_task_adapter.add(event7);

        today_task_adapter.add(new EventTypeSection("Birthday"));
        today_task_adapter.add(event8);
        today_task_adapter.add(event9);

        task_list.setAdapter(today_task_adapter);

        return view;
    }

    private void eventCreation()
    {
        event = new Schedule(1,"Algorythm Theory", ScheduleType.LESSON, "10:20 AM", "11:55 AM", "07.01.2017", EventType.SCHEDULE, "Waiting", 79);
        event1 = new Schedule(2,"Object-oriented programming", ScheduleType.LABORATORY_WORK, "12:00 AM", "01:30 PM", "07.01.2017", EventType.SCHEDULE, "Waiting", 63);
        event3 = new Schedule(2,"Aplied Math", ScheduleType.EXAM, "01:50 PM", "03:35 PM", "07.01.2017", EventType.SCHEDULE, "Waiting", 17);

        event4 = new ToDo(5,"Clean house", "09:30 AM", "03:35 PM", "07.01.2017", EventType.TODO, "Waiting", 91);
        event5 = new ToDo(7,"Buy grocery and other things", "01:30 AM", "02:25 PM", "07.01.2017", EventType.TODO, "Waiting", 23);

        event6 = new WorkTask(5,"Refactoring", "09:30 AM", "01:35 PM", "07.01.2017", EventType.WORKTASK, "Waiting", 81);
        event7 = new WorkTask(7,"Build database", "04:30 PM", "05:25 PM", "07.01.2017", EventType.WORKTASK, "Waiting", 33);

        event8 = new Birthday(8,"Taras's birthday", "09:30 AM", "01:35 PM", "07.01.2017", EventType.BIRTHDAY, "Waiting", 71, new Location(1, 2, "Roksolany", "Lviv", "Ukraine"));
        event9 = new Birthday(9,"John's birthday", "04:30 PM", "05:25 PM", "07.01.2017", EventType.BIRTHDAY, "Waiting", 53, new Location(1, 2, "Roksolany", "Lviv", "Ukraine"));
    }
}

今日任务适配器

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.twinkle94.dealwithit.R;
import com.example.twinkle94.dealwithit.events.Event;
import com.example.twinkle94.dealwithit.events.task_types.Schedule;
import com.example.twinkle94.dealwithit.events.type_enums.EventType;

import java.util.ArrayList;
import java.util.List;

public class TodayTaskAdapter extends ArrayAdapter
{
    private final String NAME = TodayTaskAdapter.class.getSimpleName();

    private static final int TYPE_HEADER = 0;
    private static final int TYPE_LIST = 1;

    private List<Item> list_of_tasks = new ArrayList<>();

    public TodayTaskAdapter(Context context, int resource)
    {
        super(context, resource);
    }

    public void add(Item event)
    {
        list_of_tasks.add(event);
    }

    @Override
    public int getCount()
    {
        return list_of_tasks.size();
    }

    @Nullable
    @Override
    public Item getItem(int position)
    {
        return list_of_tasks.get(position);
    }

    @Override
    public int getItemViewType(int position)
    {
        return getItem(position).getType() == EventType.NO_TYPE ?
                RowType.HEADER_ITEM.ordinal()
                :
                RowType.LIST_ITEM.ordinal();
    }

    @Override
    public int getViewTypeCount()
    {
        return RowType.values().length;
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent)
    {
        EventViewHolder eventViewHolder;

        // Get the data item type for this position
        int type = getItemViewType(position);

        if(convertView == null)
        {
            eventViewHolder = new EventViewHolder();

            // Inflate XML layout based on the type
            convertView = getInflatedLayoutForType(type, parent);

            switch (type)
            {
                case TYPE_HEADER:
                    initHeader(convertView, eventViewHolder);
                    break;

                case TYPE_LIST:
                    initViews(convertView, eventViewHolder);
                    break;
            }

            convertView.setTag(eventViewHolder);
        }

        else
        {
            eventViewHolder = (EventViewHolder) convertView.getTag();
        }

        //set all views with values from list
        setViewValues(position, eventViewHolder);

        return convertView;
    }

    private void setViewValues(int position, EventViewHolder eventViewHolder)
    {
        Item event = getItem(position);

        int type_color;
        String task_title;
        String from_time;
        String to_time;
        String importance;
        String interest;

        if (event != null)
        {
            switch (event.getType())
            {
                case SCHEDULE:
                    type_color = ContextCompat.getColor(getContext(), R.color.colorTypeSchedule);
                    task_title = ((Event)(event)).getTitle();
                    String schedule_type = ((Schedule)(event)).getScheduleType().toString();
                    int schedule_type_image = getSchedule_type_image(event);
                    from_time = ((Event)(event)).getTime_start();
                    to_time = ((Event)(event)).getTime_end();
                    importance = Integer.toString(((Event)(event)).getImportance()) + "%";
                    interest = Integer.toString(((Event)(event)).getImportance() + 9) + "%";

                    eventViewValues(eventViewHolder, type_color, task_title, schedule_type_image, schedule_type, from_time, to_time, importance, interest, View.VISIBLE, View.VISIBLE);
                    break;

                case TODO:
                    type_color = ContextCompat.getColor(getContext(), R.color.colorTypeToDo);
                    task_title = ((Event)(event)).getTitle();
                    from_time = ((Event)(event)).getTime_start();
                    to_time = ((Event)(event)).getTime_end();
                    importance = Integer.toString(((Event)(event)).getImportance()) + "%";
                    interest = Integer.toString(((Event)(event)).getImportance() + 9) + "%";

                    eventViewValues(eventViewHolder, type_color, task_title, 0, "", from_time, to_time, importance, interest, View.GONE, View.GONE);
                    break;

                case WORKTASK:
                    type_color = ContextCompat.getColor(getContext(), R.color.colorTypeWorkTasks);
                    task_title = ((Event)(event)).getTitle();
                    from_time = ((Event)(event)).getTime_start();
                    to_time = ((Event)(event)).getTime_end();
                    importance = Integer.toString(((Event)(event)).getImportance()) + "%";
                    interest = Integer.toString(((Event)(event)).getImportance() + 9) + "%";

                    eventViewValues(eventViewHolder, type_color, task_title, 0, "", from_time, to_time, importance, interest, View.GONE, View.GONE);
                    break;

                case BIRTHDAY:
                    type_color = ContextCompat.getColor(getContext(), R.color.colorTypeBirthday);
                    task_title = ((Event)(event)).getTitle();
                    from_time = ((Event)(event)).getTime_start();
                    to_time = ((Event)(event)).getTime_end();
                    importance = Integer.toString(((Event)(event)).getImportance()) + "%";
                    interest = Integer.toString(((Event)(event)).getImportance() + 9) + "%";

                    eventViewValues(eventViewHolder, type_color, task_title, 0, "", from_time, to_time, importance, interest, View.GONE, View.GONE);
                    break;

                case NO_TYPE:
                    String type = ((EventTypeSection) getItem(position)).getTitle();

                    eventViewHolder.headerText.setText(type);

                    switch(type)
                    {
                        case "Schedule":
                            eventViewHolder.headerText.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorTypeSchedule));
                            break;

                        case "ToDo":
                            eventViewHolder.headerText.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorTypeToDo));
                            break;

                        case "Work Task":
                            eventViewHolder.headerText.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorTypeWorkTasks));
                            break;

                        case "Birthday":
                            eventViewHolder.headerText.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorTypeBirthday));
                            break;

                    }

                    break;

                //TODO: add default, when task have no type.
            }
        }
    }

    private int getSchedule_type_image(Item event)
    {
        int schedule_type_image = R.drawable.ic_lesson_type;

        switch(((Schedule)(event)).getScheduleType())
        {
            case LESSON:
                schedule_type_image = R.drawable.ic_lesson_type;
                break;

            case EXAM:
                schedule_type_image = R.drawable.ic_exam_schedule_type;
                break;

            case LABORATORY_WORK:
                schedule_type_image = R.drawable.ic_lab_work_schedule_type;
                break;
        }
        return schedule_type_image;
    }

    //TODO: overload method with less parameters for different types of tasks.
    private void eventViewValues(EventViewHolder eventViewHolder, int type_color, String task_title, int scheduleTypeImage, String schedule_type,
                                 String from_time, String to_time, String importance, String interest,
                                 int task_type_visibility, int task_type_image_visibility)
    {
        eventViewHolder.type_color.setBackgroundColor(type_color);

        eventViewHolder.task_title.setText(task_title);
        eventViewHolder.task_type.setText(schedule_type);
        eventViewHolder.task_type_image.setImageResource(scheduleTypeImage);

        eventViewHolder.task_type.setVisibility(task_type_visibility);
        eventViewHolder.task_type_image.setVisibility(task_type_image_visibility);

        eventViewHolder.from_title.setText("From");
        eventViewHolder.from_time.setText(from_time);
        eventViewHolder.from_image.setImageResource(R.drawable.ic_from_time);

        eventViewHolder.to_title.setText("To");
        eventViewHolder.to_time.setText(to_time);
        eventViewHolder.to_image.setImageResource(R.drawable.ic_to_time);

        eventViewHolder.importance.setText(importance);
        eventViewHolder.importance_image.setImageResource(R.drawable.ic_importance_icon);

        eventViewHolder.interest.setText(interest);
        eventViewHolder.interest_image.setImageResource(R.drawable.ic_interest_today_page);
    }

    private View getInflatedLayoutForType(int type, ViewGroup parent)
    {
        LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View inflated_view = null;

        switch(type)
        {
            case TYPE_HEADER:
                inflated_view = layoutInflater.inflate(R.layout.today_list_header, parent, false);
                break;

            case TYPE_LIST:
                inflated_view = layoutInflater.inflate(R.layout.today_list_item, parent, false);
                break;
        }

        return inflated_view;
    }

    private void initHeader(View row, EventViewHolder eventViewHolder)
    {
        eventViewHolder.headerText = (TextView) row.findViewById(R.id.tasks_title);
    }

    private void initViews(View row, EventViewHolder eventViewHolder)
    {
        eventViewHolder.type_color = row.findViewById(R.id.type_color);

        eventViewHolder.task_title = (TextView) row.findViewById(R.id.task_title);
        eventViewHolder.task_type = (TextView) row.findViewById(R.id.task_type);
        eventViewHolder.task_type_image = (ImageView) row.findViewById(R.id.lesson_type);

        eventViewHolder.from_title = (TextView) row.findViewById(R.id.from_title);
        eventViewHolder.from_time = (TextView) row.findViewById(R.id.from_time);
        eventViewHolder.from_image = (ImageView) row.findViewById(R.id.from_time_icon);

        eventViewHolder.to_title = (TextView) row.findViewById(R.id.to_title);
        eventViewHolder.to_time = (TextView) row.findViewById(R.id.to_time);
        eventViewHolder.to_image = (ImageView) row.findViewById(R.id.to_time_icon);

        eventViewHolder.importance = (TextView) row.findViewById(R.id.importance_percent);
        eventViewHolder.importance_image = (ImageView) row.findViewById(R.id.importance_icon);

        eventViewHolder.interest = (TextView) row.findViewById(R.id.interest_percent);
        eventViewHolder.interest_image = (ImageView) row.findViewById(R.id.interest_icon);
    }

    private static class EventViewHolder
    {
        View type_color;

        TextView task_title;
        TextView task_type;
        ImageView task_type_image;

        TextView from_title;
        TextView from_time;
        ImageView from_image;

        TextView to_title;
        TextView to_time;
        ImageView to_image;

        TextView importance;
        ImageView importance_image;

        TextView interest;
        ImageView interest_image;

        //Header text
        TextView headerText;
    }

    private enum RowType
    {
        HEADER_ITEM, LIST_ITEM
    }
}

最佳答案

由于各种原因,列表可能需要很长时间才能加载:数据大小、与后端服务器的连接速度慢、计算需求高等。通常这些耗时的任务只是需要一些时间而没有什么我们可以做的只是尽量减少对用户的影响。

使用 AsyncTaskLoader 等进行后台处理的目的是将耗时任务从运行用户界面的线程中移出(UI 线程)和尽可能多的重叠处理,这样应用程序就不会出现“挂起”。因此,请尽快启动 AsyncTask。根据您的应用程序,处理可能会在用户需要查看结果数据时完成,这会很棒。如果没有,那么您可能需要抛出一个 ProgressBar 来让他们知道他们需要稍等片刻。 AsyncTaskonPreExecute()onProgressUpdate()onPostExecute() 方法将帮助您与用户沟通(在 UI 线程上)关于您的应用程序在获取数据方面取得的进展。查看documentation .

另请查看 this example . AsyncTaskListView 适配器设置后立即被调用。这是执行此操作的常见位置。那将在您的 fragment 中。 (getView() 不是正确的地方。)

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

adpt = new SimpleAdapter(new ArrayList(), this);
ListView lView = (ListView) findViewById(R.id.listview);

lView.setAdapter(adpt);

// Exec async load task
(new AsyncListViewLoader()).execute("http://10.0.2.2:8080/JSONServer/rest/ContactWS/get");
}

如果您有大量数据要显示,那么您可能需要实现一些逻辑来进行无限滚动,在获取更多数据之前先显示一两页数据。只需搜索“listView endless scrolling”即可了解更多相关信息。

希望对您有所帮助。

关于android - 如何将 AsyncTask 与 ListView 适配器一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42602729/

相关文章:

android - 获取错误此 Android SDK 需要 Android 开发人员工具包版本 23.0.0 或更高版本,即使它已经安装

java - 您可以在 Android 上使用 Bloomberg API 吗?

c# - 上下文菜单 - 我如何知道哪个控件激活了它

java - 解析XML,我没有错误,我不知道出了什么问题?

android - 如何在 TabLayout 中的选项卡之间添加边距?

Android 无法使用前置摄像头录制视频,MediaRecorder 启动失败 : -19

android - 如何从 ArrayAdapter 中的 onClickListener 重新加载 Activity

android - 在带有 React Native 的 Android 中使用 ListView onEndReached 无法按预期工作

Android 应用程序在单独文件中调用函数时崩溃

java - 需要从 AsyncTask 返回值