ListVeew in Fragment Very Laggy

时间:2016-03-15 03:40:02

标签: java android listview android-fragments

我有一个包含3个片段的ViewPager。最右边的片段里面有一个ListView。问题是,在我测试过的两款较弱的手机上,它看起来很平滑而且没有延迟。但是,当我在Note 3上测试时,从中间片段到此片段的转换非常滞后,根据logcat跳过超过300帧。此外,如果我锁定手机然后将其解锁回ListView,则滚动或执行任何操作都会非常滞后,除非我向左滑动两次到最左边的片段。这是我的onCreateView,onAttach和onStart方法以及下面的适配器。

@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.fragment_c,container,false);
    mainalyout = (LinearLayout) view.findViewById(R.id.linear_layout_listview);
    listView =  (ListView) view.findViewById(R.id.followed_cities);
    horizontal_scroll = (HorizontalScrollView) view.findViewById(R.id.horizontal_scroll_view);
    swipe = (LinearLayout) view.findViewById(R.id.scroll_up);
    layout =  (LinearLayout) view.findViewById(R.id.scroll_view_layout);
    swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_layout);
    return view;

}
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    context = MyApp.getContext();
    session = new SessionManager(context);
    userString = session.getUserDetails();
    username = userString.get("username");
    viewPager = (ViewPager) activity.findViewById(R.id.pic_pager);
    parent = (FragmentActivityTesting) activity;
    username = userString.get("username");
    queue = Volley.newRequestQueue(context);
    followed_cities = session.getFollowedCities();
    try {
        citysearcher = (citysearcher) activity;
    } catch(Exception e) {}
    try {
        slideshowready = (slideshowready) activity;
    }catch (Exception e) {}


}
@Override
public void onActivityCreated(Bundle savedInstanceState) {

    super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
    super.onStart();
    swipeRefreshLayout.setOnRefreshListener(this);
    if (followed_cities.contains("")) {
        followed_cities.clear();
    }
    if (getActivity().getIntent().getStringExtra("launcher").equals("add")) {
        get_followed(username);
    }
    if (followed_cities.isEmpty()) {
        followed_cities.add(new CityShort("","NONE"));
        ArrayAdapter<CityShort> adapter = new EmptyAdapter();
        adapterr = adapter;
        listView.setAdapter(adapterr);
    }
    else {
        ArrayAdapter<CityShort> adapter = new MyListAdapter();
        adapterr = adapter;
        listView.setAdapter(adapterr);
    }

我的适配器:

private class MyListAdapter extends ArrayAdapter<CityShort> {
    public MyListAdapter() {
        super(getActivity(), R.layout.followed_item, followed_cities);

    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        itemView = convertView;
        if (itemView == null) {
            itemView = getActivity().getLayoutInflater().inflate(R.layout.followed_item, parent, false);
        }
        TextView city_name = (TextView) itemView.findViewById(R.id.followed_city_txt);

        final String curr_city = followed_cities.get(position).getCityName();
        city_name.setText(curr_city);
        city_name.setTag(followed_cities.get(position).getCityId());

        if (curr_city.length() > 15) {
            city_name.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
        }
        listView.setOnTouchListener(swipeDetector);

        return itemView;


    }
    @Override

    public int getViewTypeCount() {

        return getCount();
    }

    @Override
    public int getItemViewType(int position) {

        return position;
    }
}

4 个答案:

答案 0 :(得分:0)

我看到你有2个列表视图(findViewById(R.id.followed_cities)findViewById(R.id.horizontal_scroll_view))。对于回收物品,水平列表视图没有很好地实施。

考虑使用RecyclerView更好的官方支持解决方案。它支持垂直和水平,并提供更好的性能(至少跳过的帧数将少于当前列表视图)。

答案 1 :(得分:0)

我看到两件事:

1)你有几个LinearLayouts。我不确定你的xml布局是什么样的,但如果嵌套LinearLayouts,它们肯定会减少视觉渲染时间。 RelativeLayouts效率更高(虽然我在第一次编写xml文件时会使用LinearLayouts,因为它作为常规设置对我来说耗费的时间少了一点,然后又回到并更新为使用RelativeLayout)

2)您在MainThread上进行了所有这些计算,MainThread本质上也是Android的GPU。您可能有兴趣在单独的线程上处理所有这些,这肯定会减少渲染时间。查看&#34;扩展AsyncTask&#34;和&#34;意图服务&#34;。

答案 2 :(得分:0)

更改这些内容并尝试工作..

ViewHolder holder = null;
    if (convertView == null) {
        holder = new ViewHolder();
        convertView = getActivity().getLayoutInflater().inflate(R.layout.followed_item, parent, false);
       city_name = (TextView) itemView.findViewById(R.id.followed_city_txt); //Make this class level variable
        convertView.setTag(holder);
    } else {
            holder = (ViewHolder) convertView.getTag();
    }

答案 3 :(得分:0)

Replace your adapter with this

package com.munk.gaanasync;

import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.view.LayoutInflater;

import java.util.zip.Inflater;

private class MyListAdapter extends ArrayAdapter<CityShort>
{
    public MyListAdapter()
    {
        super(getActivity(), R.layout.followed_item, followed_cities);
       mInflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent)
    {
        ViewHolder holder = null;
        itemView = convertView;
        if (itemView == null)
        {
            holder = new ViewHolder();
            itemView = mInflater.inflate(R.layout.followed_item, parent, false);
            holder.city_name = (TextView) itemView.findViewById(R.id.followed_city_txt);
            itemView.setTag(holder);
        }
        else
        {
            holder = (Viewholder) itemView.getTag();
        }

        final String curr_city = followed_cities.get(position).getCityName();
        holder.city_name.setText(curr_city);
        holder.city_name.setTag(followed_cities.get(position).getCityId());

        if (curr_city.length() > 15)
        {
            holder.city_name.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
        }
        listView.setOnTouchListener(swipeDetector);

        return itemView;
    }


    public static class ViewHolder
    {
        public TextView city_name;
    }


    @Override

    public int getViewTypeCount()
    {

        return getCount();
    }

    @Override
    public int getItemViewType(int position)
    {

        return position;
    }

    private Inflater mInflater;
}