0

I was using a custom adapter for a ListView. Basically it enters three things two textviews and an RelativeLayout. The RelativeLayout is used to display a block of colour. Previously I was using the same code below but without the ViewHolder stuff and was just calling everything from the getView() method using findViewById(). This worked perfectly. I switched to using a ViewHolder to speed up things a little and suddenly the colour blocks are not showing. All I get is all the text as it should be with a white block where the colour block should be (which is interesting since the default colour setting for the RelativeLayout background is black).

Here is the code;

public class colorlibListViewAdapterClass extends ArrayAdapter<String>
{
    //Context storage. Will be populate from creation call in display class
    private final Context context;
    //Class location to store array of HEX values - populate from class call.
    private final String[] values;
    public Typeface typeface;
    public Typeface typefaceSecond;


    static class ViewHolder
    {
        public TextView textView;
        public TextView rgbText;
        public RelativeLayout colorBlock;

    }

    public colorlibListViewAdapterClass(Context context, String[] values)
    {
        //R.layout.rowlayout is the custom look for the row. Stored in layout folder
        super(context, R.layout.rowlayout, values);
        this.context = context;
        this.values = values;

        typeface = Typeface.createFromAsset(context.getAssets(), "fonts/cabinbold.otf");
        typefaceSecond = Typeface.createFromAsset(context.getAssets(), "fonts/cabinregular.otf");


    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View rows = convertView;

        if (rows == null)
        {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rows = inflater.inflate(R.layout.rowlayout, null);
            // configure view holder
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.textView = (TextView) rows.findViewById(R.id.title);
            viewHolder.rgbText = (TextView) rows.findViewById(R.id.rbgText);
            viewHolder.colorBlock = (RelativeLayout) rows.findViewById(R.id.colorBlock);


            rows.setTag(viewHolder);
        }
        //Prepare the inflation service.


        ViewHolder holder = (ViewHolder) rows.getTag();

        //Create variables to reference the items on the Listview.
        //The ImageView is the background used to set colour and TextView is used to display HEX code.


        //Set custom font to the HEX Textview
        holder.textView.setTypeface(typeface);


        //Set Custom font to the RGB TextView
        holder.rgbText.setTypeface(typefaceSecond);




        //Create instance of libraryClass
        libraryClass colorLib = new libraryClass();

        //HERE BE CODE FOR DECIDING WHETHER RBG OR HSV

        //Variable for getting HSV
        float[] hsvReturn;
        //Get HSV - Returned as array h,s,v
        hsvReturn = colorLib.getHSV(Integer.parseInt(values[position], 16)+0xFF000000);

        //Create and initialize integer variable for conversion
        int[] hsvInt = {0,0,0};

        //Round off to get rid of excess and conver to percentage rather than 0.*
        hsvReturn[0] = Math.round(hsvReturn[0]);
        hsvReturn[1] = Math.round(hsvReturn[1] * 100);
        hsvReturn[2] = Math.round(hsvReturn[2] * 100);

        //Cast to int
        hsvInt[0] = (int)hsvReturn[0];
        hsvInt[1] = (int)hsvReturn[1];
        hsvInt[2] = (int)hsvReturn[2];

        //Variable to display
        String hsvDisplay;

        //Construct display
        hsvDisplay = Integer.toString(hsvInt[0]) + (char) 0x00B0 + " , " + Integer.toString(hsvInt[1]) + "% , " + Integer.toString(hsvInt[2]) + "%";

        //Set display
        holder.rgbText.setText(hsvDisplay);

        //Set RGB TextView
        //rgbText.setText(colorLib.hex2Rgb(values[position]));

        //Set the HEX color code name to the textview on the listview
        holder.textView.setText(values[position]);


        //Set background to defined colour. parseInt(values[position], 16)+0xFF000000) tells us it's a HEX colour without hash
        holder.colorBlock.setBackgroundColor(Integer.parseInt(values[position], 16) + 0xFF000000);


        //Text color should be ABB7B7 if sat < 14.5 and brightness > 98





        return rows;
    }
} 
Flatlyn
  • 2,040
  • 6
  • 40
  • 69
  • honestly, view holder pattern doesn't pay off, you have to add much dumb code and the benefits are minimal (yes i verified that many times) – pskink Dec 11 '14 at 09:01
  • @pskink Maybe is true for simple listview elements or high performance devices, but i don't believe it is always true. Inside the new RecyclerView.Adapter Google is officially using it. – Fabio Felici Dec 11 '14 at 09:12
  • @GonjiDev try to measure time spent in all calls to findViewById, i measured that for a list view having 100 items each one having 4 views and when scrolling from top to bottom i would save 15 ms or something... yes 15 ms! on low end device! does it pay off? – pskink Dec 11 '14 at 09:19
  • @pskink Out and interest and so I can run my own tests what are using using to get the ms time results. – Flatlyn Dec 11 '14 at 09:25
  • @GonjiDev if you have simple List items, yes. But if you have more that 10 different items and heavy hierarchy, than performance is important. – Suvitruf - Andrei Apanasik Dec 11 '14 at 09:59
  • @Suvitruf That's what I said.. – Fabio Felici Dec 11 '14 at 10:03
  • @JamesKrawczyk i used System.nanoTime and verified the results with System.currentTimeMillis measuring the multiple calls of findViewById in a loop – pskink Dec 11 '14 at 10:03

1 Answers1

1

put the below code in this function

public View getView(int position, View convertView, ViewGroup parent){}

    convertView = null;
    ViewHolder holder = null;