Martin Voroňák Martin Voroňák - 2 months ago 22
Android Question

CustomAdapter different gradient list item

I'm trying to display a

ListView
with coloured background item. Every row should have different gradient background. I've searched for some time but couldn't fix my problem. Every row has same background now - last saved profile. Moreover, I failed to set gradient as background of
TextView
that uses
rounded.xml
as background. Thanks for any help.

Screenshot of my list

Here's my
CustomAdapter
:

public class CustomAdapterProfiles extends ArrayAdapter<Profile> {

private static final String TAG = "MyActivity";
ArrayList<Profile> myArrayList = null;
PaintDrawable paint;

int[] arrColors;
int numColors;
float[] result;

Profile i;

CustomAdapterProfiles(Context context, ArrayList<Profile> menuAdapter){
super(context, R.layout.customrow , menuAdapter);
this.myArrayList = menuAdapter;
}


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

LayoutInflater listInflater = LayoutInflater.from(getContext());
View customView = listInflater.inflate(R.layout.customrow, parent, false);

i = myArrayList.get(position);
String singleItem = i.getObjectName();
TextView mobileText = (TextView) customView.findViewById(R.id.listID);
mobileText.setText(singleItem);

numColors = i.getArrayList().size();
arrColors = new int[i.getArrayList().size()];

if (numColors>1) {

//positions of colors defined by user
result = new float[numColors];
for (int a = 0; a < numColors; a++) {
result[a] = (float) i.getGradients().get(a);
}

//make sure user didnt write error values (not fixed yet)
result[0]=0;
result[numColors - 1] = 1;

//colors
for (int j = 0; j < numColors; j++) {
arrColors[j] = Integer.parseInt(i.getArrayList().get(j).toString(), 16) + 0xFF000000;
}

ShapeDrawable.ShaderFactory shaderFactory = new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
LinearGradient linearGradient = new LinearGradient(0, 0, width, height,
arrColors, //pouzity array farieb
result,
Shader.TileMode.REPEAT);
return linearGradient;
}
};
paint = new PaintDrawable();
paint.setShape(new RectShape());
paint.setShaderFactory(shaderFactory);

mobileText.setBackgroundDrawable((Drawable) paint);
}
else {
//cant set shaderFactory becouse it needs 2 or more colors
mobileText.getBackground().setColorFilter(Color.parseColor("#" + i.getArrayList().get(0).toString()), PorterDuff.Mode.SRC_ATOP);
}

return customView;
}
}

Answer

The biggest problem (i guess it was this) was using ArrayAdapter instead of BaseAdapter. I have tried (as noob android programmer) many things and tutorials, but after i tried this: enter link description here it worked. Also, as you can see, i have found solution to rounded textview (marked in code below "---"). Name of row items are set to "" so you can not see the names.

enter image description here

public class CustomListAdapter extends BaseAdapter {
private Context context; //context
private ArrayList<Profile> items; //data source of the list adapter

//public constructor
public CustomListAdapter(Context context, ArrayList<Profile> items) {
    this.context = context;
    this.items = items;
}

@Override
public int getCount() {
    return items.size(); //returns total of items in the list
}

@Override
public Object getItem(int position) {
    return items.get(position); //returns list item at the specified position
}

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

public void updateResults(ArrayList<Profile> results) {
    items = results;
    //Triggers the list update
    notifyDataSetChanged();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;

    if (convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.customrow, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    // get current item to be displayed
    Profile currentItem = (Profile) getItem(position);
    viewHolder.itemName.setText(currentItem.getObjectName());


    int numColors = currentItem.getArrayList().size();


    if (numColors > 1) {

        int[] arrColors = new int[numColors];

        //positions of colors defined by user
        final float[] result = new float[numColors];
        for (int a = 0; a < numColors; a++) {
            result[a] = (float) currentItem.getGradients().get(a);
        }

        //make sure user didnt write error values (not fixed yet)
        result[0] = 0;
        result[numColors - 1] = 1;

        //colors
        for (int j = 0; j < numColors; j++) {
            arrColors[j] = Integer.parseInt(currentItem.getArrayList().get(j).toString(), 16) + 0xFF000000;
        }

        final int[] finalArrColors = arrColors;

        ShapeDrawable.ShaderFactory shaderFactory = new ShapeDrawable.ShaderFactory() {
            @Override
            public Shader resize(int width, int height) {
                LinearGradient linearGradient = new LinearGradient(0, 0, width, height,
                        finalArrColors, //pouzity array farieb
                        result,
                        Shader.TileMode.REPEAT);
                return linearGradient;
            }
        };

        // --- rounded textView !
        PaintDrawable paint = new PaintDrawable();
        paint.setShape(new RectShape());
        paint.setShaderFactory(shaderFactory);

        paint.setCornerRadius(100);
        // --- end of rounded textView code

        viewHolder.itemName.setBackgroundDrawable(paint);
    }
    else if (numColors == 1) {
        //not important
    }
    else {
        viewHolder.itemName.setText("empty object");
    }

    return convertView;
}

private class ViewHolder {
    TextView itemName;

    public ViewHolder(View view) {
        itemName = (TextView) view.findViewById(R.id.listID);
    }
}

}

Calling the BaseAdapter:

CustomListAdapter adapter = new CustomListAdapter(this, profiles); ListView menuListView = (ListView) findViewById(R.id.listViewHS); menuListView.setAdapter(adapter); adapter.updateResults(profiles);

Profile Class:

public class Profile implements Serializable {

private String objectName;
private ArrayList<String> arrayColorList;
private ArrayList<Float> gradients;

public Profile(String objectName, ArrayList<String> arrayList, ArrayList<Float> gradients){
    this.objectName=objectName;
    this.arrayColorList=arrayList;
    this.gradients=gradients;
}

public String getObjectName() {
    return objectName;
}

public ArrayList<String> getArrayList() {
    return arrayColorList;
}

public ArrayList<Float> getGradients() {
    return gradients;
}

}

Comments