ViewPager.setAdapter执行需要200ms到300ms

时间:2015-12-27 12:18:44

标签: java android android-fragments android-asynctask

我的ViewPager有一点UI问题。

我的ViewPager是我的UI的中心。

我有一个包含4个项目的NavigationView和一个包含2个项目的工具栏。

每次单击NavigationView的项目时,我都会更换适配器。因此,我有4个适配器,只有一个导致问题:BrowseAdapter(代码如下)。

此适配器填充了事件列表,并为每个事件提供片段。

值得注意的是,无论eventList的大小如何,ViewPager的setAdapter方法至少需要150ms才能执行,而对于其他适配器,只需要20到50ms即可加载。

我试图在View.post(new Runnable());方法和AsyncTask<Void, Void, Void>中对setAdapter进行所有调用:

  • post方法冻结了用户界面

  • AsyncTask没有任何改变,因为我只能在UI线程上调用setAdapter(在postExecute方法中),这与没有AsyncTask时调用它基本相同。

我认为这基本上是一个优化问题,但我看不出问题出在哪里。

谢谢你的帮助。

以下是相关代码:

MainActivity:

/*
.
. Import stuff
.
.
.*/

public class MainActivity extends AppCompatActivity implements RequestCallback,
ConnectionCallbacks, OnConnectionFailedListener, FBLoginChanged, LocationListener {


/**
 * The main content view
 */
private CustomViewPager mViewPager;

/**
 * Adapters : One for each feature of the application
 */
private BrowseAdapter mBrowseAdapter;
private CurrentAdapter mCurrentAdapter = new CurrentAdapter(getFragmentManager());
private CalendarAdapter mCalendarAdapter = new CalendarAdapter(getFragmentManager());
private SettingsAdapter mSettingsAdapter = new SettingsAdapter(getFragmentManager());

/**
 * The action bar of the application
 */
private Toolbar mToolbar;
/**
 * TabLayout provide the new Material Design tab navigation
 */
private TabLayout mTabLayout;
/**
 * Side navigation given by a NavigationView instead of a NavigationDrawer
 * to support Material Design
 */
private NavigationView mNavigationView;
private DrawerLayout mDrawerLayout;

/**
 * List of all events.
 */
private ArrayList<Event> mEventList = new ArrayList<Event>();

/**
 * Provide different way of browsing through the events
 */
private enum BrowseType {
    DEFAULT,
    POPULAR,
    RANDOM
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    /*.
    .
    . Initialization stuff
    .
    .*/

    //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
    mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

        // This method will trigger on item Click of navigation menu
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) {

            //Closing drawer on item click
            mDrawerLayout.closeDrawers();

            //Check to see which item was being clicked and perform appropriate action
            switch (menuItem.getItemId()){
            case R.id.home:
                mTabLayout.setVisibility(View.VISIBLE);
                mBrowseAdapter.setBrowsingType(BrowseType.DEFAULT);
                mViewPager.setAdapter(mBrowseAdapter);
                break;
            case R.id.favs:
                mTabLayout.setVisibility(View.GONE);
                mViewPager.setAdapter(mCurrentAdapter);
                break;
            case R.id.calendar:
                mTabLayout.setVisibility(View.GONE);
                mViewPager.setAdapter(mCalendarAdapter);
                break;
            case R.id.setting:
                mTabLayout.setVisibility(View.GONE);
                mViewPager.setAdapter(mSettingsAdapter);
                break;
            default:
                break;
            }

            return true;
        }
    });

    mViewPager = (CustomViewPager) findViewById(R.id.pager);

    mBrowseAdapter = new BrowseAdapter(this.getFragmentManager(), mEventList);

    mTabLayout.setOnTabSelectedListener(new OnTabSelectedListener() {

        @Override
        // Unused
        public void onTabReselected(Tab tab) {

        }

        @Override
        public void onTabSelected(Tab tab) {
            switch(tab.getPosition()) {
            case 0:
                mBrowseAdapter.setBrowsingType(BrowseType.DEFAULT);
                break;
            case 1: 
                mBrowseAdapter.setBrowsingType(BrowseType.POPULAR);
                break;
            default: // Unused
                break;
            }
            mViewPager.setAdapter(mBrowseAdapter);
        }
        @Override
        // Unused
        public void onTabUnselected(Tab tab) {

        }

    });

    mViewPager.setAdapter(mBrowseAdapter);
}

}

我的适配器:

private class BrowseAdapter extends FragmentStatePagerAdapter {

private ArrayList<Event> eventList = new ArrayList<Event>();
private BrowseType browseType = BrowseType.DEFAULT;
private HashMap<Integer, EventFragment> fragmentReferenceMap = new HashMap<Integer, EventFragment>();

public BrowseAdapter(FragmentManager fragmentManager,
        ArrayList<Event> mEventList) {
    super(fragmentManager);
}

public void setBrowsingType(BrowseType type) {
    this.browseType = type;
    this.commitChanges();
}

public Event getEventById(int id) {
    for(Event event : eventList) {
        if(event.getId() == id)
            return event;
    }
    return null;
}

public void setJSONData(JSONArray jsonArray) {
    for (int i = 0; i < jsonArray.length(); i++) {
        try {
            JSONObject obj = jsonArray.getJSONObject(i);
            Event event = new Event();
            event.setId(obj.getInt("id"));
            event.setName(obj.getString("name"));
            event.setShort_description(obj.getString("short_desc"));
            event.setLong_description(obj.getString("long_desc"));
            event.setPlace(obj.getString("place").split(";")[0]);
            Location loc = new Location("");
            loc.setLatitude(Double.valueOf(obj.getString("place")
                    .split(";")[1]));
            loc.setLongitude(Double.valueOf(obj.getString("place")
                    .split(";")[2]));
            event.setLocation(loc);
            event.setDate(obj.getString("date"));
            eventList.add(event);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

public String getJSONData() {
    JSONArray toReturn = new JSONArray();
    for (Event event : eventList) {
        JSONObject tmp = new JSONObject();
        try {
            tmp.put("name", event.getName());
            tmp.put("short_desc", event.getShort_description());
            tmp.put("long_desc", event.getLong_description());
            tmp.put("id", event.getId());
            tmp.put("date", event.getDate());
            tmp.put("place",
                    event.getPlace()
                    + ";"
                    + String.valueOf(event.getLocation()
                            .getLatitude())
                            + ";"
                            + String.valueOf(event.getLocation()
                                    .getLongitude()));
            toReturn.put(tmp);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return toReturn.toString();
}

public boolean addItem(Event item) {
    return eventList.add(item);
}

@SuppressWarnings("unused")
public Event removeAt(int position) {
    return eventList.remove(position);
}

public void commitChanges() {
    this.sort();
    this.notifyDataSetChanged();
}

private void sort() {
    Log.d("SORT", browseType.name());
    Collections.sort(eventList, new Comparator<Event>() {
        @Override
        public int compare(Event arg0, Event arg1) {
            float dis1 = arg0.getLocation().distanceTo(
                    LocationProvidor.getInstance().getLastLocation());
            float dis2 = arg1.getLocation().distanceTo(
                    LocationProvidor.getInstance().getLastLocation());
            int userNumber1 = Integer.parseInt(arg0.getUserNumber());
            int userNumber2 = Integer.parseInt(arg1.getUserNumber());
            switch(browseType) {
            case DEFAULT:
                return (int) (dis1 - dis2);
            case POPULAR:
                return userNumber2 - userNumber1;
            case RANDOM:
                return new Random().nextInt();
            default:
                return 0;
            }
        }

    });
}

public void empty() {
    eventList.clear();
}

@Override
public EventFragment getItem(int position) {
    EventFragment frag = EventFragment.newInstance(eventList.get(position));
    frag.setIsCurrents(mCurrentAdapter.containsEventId(eventList.get(position).getId()));
    fragmentReferenceMap.put(position, frag);
    return frag;
}

@Override
public void destroyItem(View container, int position, Object object) {
    super.destroyItem(container, position, object);
    fragmentReferenceMap.remove(position);
    Log.d("fr.blopper.app", "destroy " + position);
}

public EventFragment getFragment(int position) {
    return fragmentReferenceMap.get(position);
}

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

和CustomViewPager(我创建它只是为了测量setAdapter所花费的时间):

import android.content.Context;
import android.util.AttributeSet;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.support.v4.view.PagerAdapter;


public class CustomViewPager extends ViewPager {

public CustomViewPager(Context c) {
    super(c);
}

public CustomViewPager(Context c, AttributeSet as) {
    super(c, as);
}

@Override
public void setAdapter(PagerAdapter adapter) {
    long start = System.currentTimeMillis();
    super.setAdapter(adapter);
    Log.d("TAG", "Custom time " + (System.currentTimeMillis() - start));
}
}

1 个答案:

答案 0 :(得分:1)

找到答案,它与ViewPager无关。

适配器提供的片段正在调用Google API,但答案很慢。