Search code examples
androidlistviewbaseadaptersmooth-scrolling

Solved: ListView not getting scrolled smoothly and it stucks/crashes while scrolling even with ViewHolder


Here I'm getting lots of data from web services and I have attached an image of list item too. But my ListView gets stuck or crash when I scroll it. It has lots of data as you can see. I've tried many things but nothing is worth to me.

MainActivity.java

lv = (ListView) findViewById(R.id.script_list);
lv.setScrollingCacheEnabled(false);
lv.setFastScrollEnabled(true);

//AsynTask
public class PostReview extends AsyncTask<Void, Void, String> {
    ProgressBar progressBar;
    String posted_by = "";

    public PostReview(Context con, String item, ProgressBar progressBar) {
        this.posted_by = item;
        this.progressBar = progressBar;

    }

    //
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        /*pDialog = new ProgressDialog(ScriptViewClick.this, AlertDialog.THEME_HOLO_DARK);
        pDialog.setMessage("Please Wait ..... ");
        pDialog.setCancelable(false);
        pDialog.show();*/
        // progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected String doInBackground(Void... params) {
        return getString();
    }

    private String getString() {
        // TODO Auto-generated method stub

        String POST_PARAMS = "adivsor_id=" + posted_by;

        URL obj = null;
        HttpURLConnection con = null;
        try {
            obj = new URL(Constants.AppBaseUrl + "/advisor_calls/");
            String userPassword = "rickmams" + ":" + "advisor11";
            String header = "Basic " + new String(android.util.Base64.encode(userPassword.getBytes(), android.util.Base64.NO_WRAP));
            con = (HttpURLConnection) obj.openConnection();
            con.addRequestProperty("Authorization", header);
            con.setRequestMethod("POST");

            // For POST only - BEGIN
            con.setDoOutput(true);
            OutputStream os = con.getOutputStream();
            os.write(POST_PARAMS.getBytes());
            os.flush();
            os.close();
            // For POST only - END

            int responseCode = con.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) { // success
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        con.getInputStream()));
                String inputLine;
                StringBuffer response = new StringBuffer();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                Log.i("TAG21", response.toString());
                if (response.toString() != null) {
                    JSONObject jsonObject;

                    try {
                        jsonObject = new JSONObject(response.toString());
                        JSONArray js = jsonObject.getJSONArray("list");
                        for (int ii = 0; ii < js.length(); ii++) {
                            JSONObject c = js.getJSONObject(ii);
                            EquityDetails allDirectory = new EquityDetails();
                            allDirectory.setEntry_value(c.getString("entry"));
                            String value1 = c.getString("entry");
                            allDirectory.setCall_id(c.getString("call_id"));
                            String value2 = c.getString("tgt_1");
                            allDirectory.setSerial_value(c.getString("sl"));
                            allDirectory.setTg_value1(c.getString("tgt_1"));
                            allDirectory.setTg_value2(c.getString("tgt_2"));
                            allDirectory.setMainTitle_value(c.getString("script"));
                            allDirectory.setMain_subTitle_value(c.getString("exchange"));
                            allDirectory.setRating_value(c.getString("rating"));
                            allDirectory.setReview_value(c.getString("review"));
                            allDirectory.setPosted_by(c.getString("posted_by"));

                            allDirectory.setImage1(c.getString("advisor_image"));
                            allDirectory.setImage2(c.getString("script_image"));
                            allDirectory.setBuy(c.getString("buy_sentiment"));
                            allDirectory.setSell(c.getString("sell_sentiment"));
                            allDirectory.setRecommend(c.getString("recommendation"));
                            allDirectory.setPosted_date(c.getString("posted_date"));
                            allDirectory.setExpiry_date(c.getString("expiry_date"));
                            catListDao.add(allDirectory);

                        }

                        sca = new ScriptViewAdapter(getApplicationContext(), catListDao);
                        lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
  } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                return response.toString();

            } else {
                Log.i("TAG12", "POST request did not work.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        lv.setAdapter(sca);


    }
}

BaseAdapter of the class

 public ScriptViewAdapter(Context com, List<EquityDetails> list) {

    this.con = com;
    this.items = list;

}

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

@Override
public Object getItem(int position) {
    return items.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) con
                .getSystemService(con.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.script, null);
holder = new ViewHolder();
        holder.tv_rating_title = (TextView) convertView
                .findViewById(R.id.script_tv_rating_title);
} else
         holder = (ViewHolder) convertView.getTag();
Picasso.with(con)
            .load(items.get(position).getImage1())
            .into(holder.scriptView);
    Picasso.with(con)
            .load(items.get(position).getImage2())
            .into(holder.advisoryView);
    // new DownloadImageTask(holder.advisoryView).execute(items.get(position).getImage1());
    //    new DownloadImageTask(holder.scriptView).execute(items.get(position).getImage2());
    return convertView;
}

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/percentage_text_top_margin"
android:background="@android:color/black"
android:gravity="center"
android:orientation="vertical">

<LinearLayout
    android:id="@+id/script_elements_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginBottom="2dp"
    android:layout_marginTop="@dimen/percentage_text_top_margin"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/script_tv_element"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/et_topPadding"
        android:textColor="@color/text_color"
        android:textSize="@dimen/home_screen_top_text"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/script_tv_mcx"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/text_color"
        android:textSize="@dimen/home_screen_top_text"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/script_tv_year"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/green"
        android:textSize="@dimen/home_screen_main_text" />


    <TextView
        android:id="@+id/script_tv_rating"
        android:layout_width="@dimen/rating_number_bg_width"
        android:layout_height="@dimen/rating_number_bg_height"
        android:layout_marginLeft="@dimen/percentage_text_top_margin"
        android:layout_marginRight="@dimen/percentage_text_top_margin"
        android:background="@drawable/rating_bg"
        android:gravity="center"
        android:paddingRight="5dp"
        android:text="50"
        android:textColor="#FCD730"
        android:textSize="@dimen/home_screen_top_text" />

    <TextView
        android:id="@+id/script_tv_review_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="@dimen/percentage_text_top_margin"
        android:text="  Review "
        android:textColor="@color/text_color"
        android:textSize="@dimen/home_screen_main_text"
        android:textStyle="bold" />

    <RatingBar
        android:id="@+id/script_rating"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/rating_bar_height"
        android:layout_gravity="center"
        android:layout_marginLeft="@dimen/percentage_text_top_margin"
        android:layout_marginRight="@dimen/percentage_text_top_margin"
        android:clickable="false"
        android:focusable="false"
        android:isIndicator="true"
        android:numStars="5"
        android:progressDrawable="@drawable/custom_star_rating" />

    <TextView
        android:id="@+id/script_tv_rating_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="  Rating"
        android:textColor="@color/text_color"
        android:textSize="@dimen/home_screen_main_text"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/script_tv_rating_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/percentage_text_top_margin"
        android:paddingLeft="5dp"
        android:text="3"
        android:textColor="@color/text_color"
        android:textSize="@dimen/home_screen_main_text" />

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/color_bg_drawer_first">

        <ImageView
            android:id="@+id/script_iv_logo"
            android:layout_width="@dimen/home_screen_image_width"
            android:layout_height="@dimen/home_screen_image_height"
            android:layout_alignParentLeft="true"
            android:layout_marginRight="5dp"
            android:background="@drawable/script_img"
            android:scaleType="fitXY" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/script_layout_company_images"
            android:layout_toRightOf="@+id/script_iv_logo"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:layout_marginTop="5dp"
                android:orientation="horizontal"
                android:weightSum="2">

                <TextView
                    android:id="@+id/tv_entry"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="@string/entry"
                    android:textColor="@color/green"
                    android:textSize="@dimen/home_screen_main_text"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/script_tv_entry_value"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="2dp"
                    android:layout_weight="1"
                    android:text="105.35"
                    android:textColor="@color/text_color"
                    android:textSize="@dimen/home_screen_main_text"
                    android:textStyle="bold" />

                <View
                    android:layout_width="@dimen/view_line_width"
                    android:layout_height="@dimen/view_line_height"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:background="@color/text_color"
                    android:visibility="gone" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:weightSum="2">

                <TextView
                    android:id="@+id/tv_serial_line"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="@string/serial"
                    android:textColor="@color/green"
                    android:textSize="@dimen/home_screen_main_text"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/script_tv_serial_line_value"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="2dp"
                    android:layout_weight="1"
                    android:text="452.00"
                    android:textColor="@color/text_color"
                    android:textSize="@dimen/home_screen_main_text"
                    android:textStyle="bold" />

                <View
                    android:layout_width="@dimen/view_line_width"
                    android:layout_height="@dimen/view_line_height"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"
                    android:background="@color/text_color"
                    android:visibility="gone" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/tv_tgt"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="@string/tgt"
                    android:textColor="@color/green"
                    android:textSize="@dimen/home_screen_main_text"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/script_tv_tgt_value"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="2dp"
                    android:layout_weight="1"
                    android:text="104"
                    android:textColor="@color/text_color"
                    android:textSize="@dimen/home_screen_main_text"
                    android:textStyle="bold" />
            </LinearLayout>


            <TextView
                android:id="@+id/script_tv_sentimenst"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="@dimen/edittext_side_margin"
                android:text="@string/sentiments"
                android:textColor="@color/text_color"
                android:textSize="@dimen/home_screen_main_text"
                android:textStyle="bold"
                android:visibility="gone" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/script_layout_company_images"
            android:layout_width="wrap_content"
            android:layout_height="@dimen/home_screen_image_small_height"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:orientation="horizontal"
            android:weightSum="2">

            <TextView
                android:id="@+id/script_iv_icon_sell"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#ff1919"
                android:gravity="center"
                android:inputType="textCapCharacters"
                android:text="recommedn"
                android:textColor="#FFF"
                android:textSize="@dimen/home_screen_main_text"
                android:textStyle="bold" />

            <ImageView
                android:id="@+id/script_iv_icon_company"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@drawable/small_script"
                android:scaleType="fitXY" />

        </LinearLayout>
    </RelativeLayout>
</LinearLayout>

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:layout_marginTop="2dp"
    android:background="@color/color_bg_drawer_first" />
</LinearLayout>

The stacktrace when app crashes on scroll is

 12-12 13:15:58.188 9104-9104/com.package E/filemap: mmap(0,154425) failed: Out of memory
 12-12 13:15:58.188 9104-9104/com.package E/InputEventReceiver: Exception dispatching input event.
 12-12 13:15:58.188 9104-9104/com.package E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
 12-12 13:15:58.218 9104-9104/com.package E/MessageQueue-JNI: java.lang.RuntimeException: native typeface cannot be made
                                                                       at android.graphics.Typeface.<init>(Typeface.java:334)
                                                                       at android.graphics.Typeface.createFromAsset(Typeface.java:308)
                                                                       at com.package.adapters.ScriptViewAdapter.getView(ScriptViewAdapter.java:116)
                                                                       at android.widget.AbsListView.obtainView(AbsListView.java:2712)
                                                                       at android.widget.ListView.makeAndAddView(ListView.java:1811)
                                                                       at android.widget.ListView.fillDown(ListView.java:697)
                                                                       at android.widget.ListView.fillGap(ListView.java:661)
                                                                       at android.widget.AbsListView.trackMotionScroll(AbsListView.java:6686)
                                                                       at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3920)
                                                                       at android.widget.AbsListView.onTouchMove(AbsListView.java:4772)
                                                                       at android.widget.AbsListView.onTouchEvent(AbsListView.java:4600)
                                                                       at android.view.View.dispatchTouchEvent(View.java:8135)
                                                                       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2416)
                                                                       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2140)
                                                                       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
                                                                       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
                                                                       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
                                                                       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
                                                                       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
                                                                       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
                                                                       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
                                                                       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
                                                                       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
                                                                       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
                                                                       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2422)
                                                                       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2155)
                                                                       at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2295)
                                                                       at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1622)
                                                                       at android.app.Activity.dispatchTouchEvent(Activity.java:2565)
                                                                       at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
                                                                       at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
                                                                       at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2243)
                                                                       at android.view.View.dispatchPointerEvent(View.java:8343)
                                                                       at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4767)
                                                                       at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4633)
                                                                       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4191)
                                                                       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4245)
                                                                       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4214)
                                                                       at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4325)
                                                                       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4222)
                                                                       at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4382)
                                                                       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4191)
                                                                       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4245)
                                                                       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4214)
                                                                       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4222)
                                                                       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4191)
                                                                       at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6556)
                                                                       at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6473)
                                                                       at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6444)
                                                                       at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6409)
                                                                       at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6636)
                                                                       at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
                                                                       at android.os.MessageQueue.nativePollOnce(Native Method)
                                                                    at android.os.MessageQueue.next(MessageQue

Note: The size of images are 128X66 and 259X194 pixels.


Solution

  • Accordingly to the code you posted here:

    1. Move all the setTypeFace into the if guard. It is a pretty expensive call and you don't need to do it continuously during the scroll.
    2. Avoid to instantiate SimpleDateFormat every time getView is called. It would better to provide the date in the dataset already in the correct format
    3. Declare the ViewHolder as static: public static class ViewHolder