简体   繁体   English

如何使用AsyncTask与ListView适配器

[英]How to use AsyncTask with ListView Adapter

So, I have a ListView which I'm showing on my TodayFragment . 所以,我有一个ListView ,我在TodayFragment上显示。 There are TodayTaskAdapter , that customises this list. TodayTaskAdapter ,可以自定义此列表。 When the actvity is loading, it takes a lot of time because of the list. 当加载actvity时,由于列表需要花费很多时间。 And slows down app. 并减慢应用程序。 The question is: 问题是:

How should I use AsyncTask right? 我该如何使用AsyncTask? And what is the right place to use it: 什么是正确的地方使用它:

  1. In fragment, when setting adapter; 在片段中,设置适配器时;
  2. In getView() method of adapter to do the operation there in backgroud; 在适配器的getView()方法中,在backgroud中进行操作;
  3. Or someplace else? 还是其他地方?

I'm not quite into it yet. 我还没完全了。 Need help. 需要帮忙。

TodayFragment TodayFragment

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"));
    }
}

TodayTaskAdapter TodayTaskAdapter

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
    }
}

A list may take a long time to load for various reasons: size of the data, slow connection to backend server, high computational demand, etc. Often these time-consuming tasks are just going to take some time and there is nothing we can do about it except to try to minimize the impact on the user. 由于各种原因,列表可能需要很长时间才能加载:数据大小,与后端服务器的连接速度慢,计算需求高等等。通常这些耗时的任务只需要一些时间,我们无能为力关于它,除了尽量减少对用户的影响。

The goal of doing background processing with AsyncTask , Loader , etc. is to take a time-consuming task and move it off of the thread that runs the user interface (the UI thread) and overlap processing as much as possible so the app does not appear to "hang." 使用AsyncTaskLoader等进行后台处理的目的是花费一个耗时的任务并将其从运行用户界面(UI线程)的线程移开并尽可能重叠处理,以便应用程序不会似乎“挂了”。 So, start the AsyncTask as soon as you can. 所以,尽快启动AsyncTask Depending upon your app, the processing may be completed by the time the user needs to see the resulting data which would be great. 根据您的应用程序,可以在用户需要查看结果数据时完成处理。 If not, then you may have to throw up a ProgressBar to let them know that they will need to wait a little. 如果没有,那么你可能不得不抛出一个ProgressBar让他们知道他们需要等一下。 The onPreExecute() , onProgressUpdate() and onPostExecute() methods of AsyncTask will help you communicate with the user (on the UI thread) about the progress your app is making in getting data. onPreExecute() onProgressUpdate()onPostExecute()方法AsyncTask将帮助你的用户(UI线程)关于你的应用程序中获取数据所取得的进展进行通信。 See the documentation . 请参阅文档

Also take a look at this example . 另请看一下这个例子 The AsyncTask is invoked right after the ListView adapter is set. 在设置ListView适配器后立即调用AsyncTask This is a common place to do this. 这是一个常见的地方。 That would be in your fragment. 这将在你的片段中。 ( getView() is not the right place.) 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");
}

If you have a lot of data to show, then you may want to implement some logic to do endless scrolling where you show a page or two of data before fetching more. 如果要显示大量数据,那么您可能需要实现一些逻辑来进行无限滚动,在获取更多数据之前显示一两页数据。 Just search for "listView endless scrolling" for additional information on this. 只需搜索“listView无限滚动”以获取有关此内容的更多信息。

I hope that this helps. 我希望这个对你有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM