-1

I currently have a ListView Which is being populated by a SimpleAdapter and the population is working great. Problem I am having is I cant seem to figure out how to change the background color of the ListItem LinearLayout during the onCreate. It is working perfectly fine if I click a button or do an action psychically but does not want to work if i do it in the onCreate or if I do it after populating the ListView based off of all the tables in my SQLITE database.

This code is what is changing the color.

  if(c.moveToFirst()){
            do{

                if(checkCat.moveToFirst()){

                    do{

                        if(c.getString(0).equals(checkCat.getString(0))){
                            for (int i = 0; i < adapter.getCount(); i++) {
                                final FrameLayout listItemLayout = (FrameLayout) cardList.getChildAt(i);
                                final LinearLayout lL = (LinearLayout) listItemLayout.findViewById(R.id.cardmainlayout);
                                final TextView tv = (TextView) listItemLayout.findViewById(R.id.text1);

                                if(tv.getText().toString().equals(checkCat.getString(1).trim())) {
                                    switch (c.getString(1).trim()) {

                                        case "White":

                                            lL.setBackgroundResource(R.drawable.bg_color_white);

                                            break;

                                        case "Orange":

                                            lL.setBackgroundResource(R.drawable.bg_color_orange);

                                            break;

                                        case "Red":

                                            lL.setBackgroundResource(R.drawable.bg_color_red);

                                            break;

                                        case "Green":

                                            lL.setBackgroundResource(R.drawable.bg_color_green);

                                            break;

                                        case "Purple":

                                            lL.setBackgroundResource(R.drawable.bg_color_purple);

                                            break;

                                        case "Blue":

                                            lL.setBackgroundResource(R.drawable.bg_color_blue);

                                            break;

                                    }

                                    switch (c.getString(2).trim()) {

                                        case "White":

                                            tv.setTextColor(getResources().getColor(android.R.color.white));

                                            break;

                                        case "Black":

                                            tv.setTextColor(getResources().getColor(android.R.color.black));

                                            break;

                                        case "Green":

                                            tv.setTextColor(getResources().getColor(android.R.color.holo_green_dark));

                                            break;

                                        case "Orange":

                                            tv.setTextColor(getResources().getColor(android.R.color.holo_orange_dark));

                                            break;

                                        case "Red":

                                            tv.setTextColor(getResources().getColor(android.R.color.holo_red_dark));

                                            break;

                                        case "Blue":

                                            tv.setTextColor(getResources().getColor(android.R.color.holo_blue_dark));

                                            break;

                                    }
                                }
                            }
                        }
                    }while (checkCat.moveToNext());
                }

            }while(c.moveToNext());
        }

This code is what is populating the ListView

        if (c.moveToFirst()) {
        do {
            if (!c.getString(0).contains("a")) {
                if (!c.getString(0).contains("name")) {
                    if (!c.getString(0).contains("name2")) {
                        String str = c.getString(0);
                        map = new HashMap<String, Object>();
                        map.put("title", str.toString();
                        fillMaps.add(map);
                    }
                }
            }
        } while (c.moveToNext());
    }

Also have this code which reupdates the ListView Based on categories the code is sort of working here. Problem is the first part is the same as above so it crashes and the second part does not exactly update after the adpater is refreshed. you have to click it the category button again for it to detect the adapter changed.(yes I am calling the adapter.notifyDataSetChanged().)

  if(strName.toLowerCase().equals("all")) {
        fillMaps.clear();
        Cursor c = appDB.rawQuery("SELECT name FROM sqlite_master WHERE type='table';", null);
        if (c.moveToFirst()) {
            do {
                if (!c.getString(0).contains("android_metadata")) {
                    if (!c.getString(0).contains("Name1")) {
                        if (!c.getString(0).contains("Name")) {

                            map = new HashMap<String, Object>();
                            map.put("title", c.getString(0));
                            fillMaps.add(map);
                            chkBox = 0;
                        }
                    }
                }

            } while (c.moveToNext());
        }
    }
    else {

        Cursor checkCat = appDB.rawQuery("SELECT * FROM Name", null);
        if (checkCat.moveToFirst()) {
            fillMaps.clear();
            do {
                if (checkCat.getString(0).contains(strName)) {

                    map = new HashMap<String, Object>();
                    map.put("title", checkCat.getString(1));
                    fillMaps.add(map);
                    chkBox = 0;
                }
            } while (checkCat.moveToNext());
        }

    }
    adapter.notifyDataSetChanged();

and last but not least this is my SimpleAdapter

   adapter = new SimpleAdapter(this, fillMaps, R.layout.main_c_layout, from, to) {
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View rRow = super.getView(position, convertView, parent);

            final Button vsButton = (Button) rRow.findViewById(R.id.quizListViewButton);
            final CheckBox cb = (CheckBox) rRow.findViewById(R.id.deleteCheckBox);

            TextView v = (TextView) rRow.findViewById(R.id.text1);

            final String str = v.getText().toString().replaceFirst("\\s+$", "");
            vsButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {


                    Toast.makeText(MainActivity.this, str + "", Toast.LENGTH_SHORT).show();
                }
            });


            cb.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (cb.isChecked()) {
                        chkBox++;
                    } else {
                        chkBox--;
                    }
                    if (chkBox > 1) {
                        editNoteSet.setVisibility(View.GONE);
                    } else {
                        editNoteSet.setVisibility(View.VISIBLE);
                    }
                }
            });

            return rRow;
        }
    };
    List.setAdapter(adapter);

So just to clear my question up how would you change the color of the LinearLayout that is located within the Custom ListView row.(For the record everything is populating properly I just cannot change the color.)

Also, The error I keep getting is Attempt to invoke virtual method 'android.view.View android.widget.FrameLayout.findViewById(int)' on a null object reference which makes not sense because it works when I click a button or do an action physically. Any and all help is appreciated Thank you in advance.

Solution:

Thanks to Mehrdad1373 I was able to come up with the solution. So the solution was to actually change the background in the SimpleAdapter getView method. I didn't realize that the simple adapter was getting called everytime a row was removed or added. So this is what I did..

adapter = new SimpleAdapter(this, fillMaps, R.layout.main_c_layout, from, to) {
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View rRow = super.getView(position, convertView, parent);

        final Button vsButton = (Button) rRow.findViewById(R.id.quizListViewButton);
        final CheckBox cb = (CheckBox) rRow.findViewById(R.id.deleteCheckBox);
        LinearLayout lL = (LinearLayout)rRow.findViewById(R.id.myLayout);
        TextView v = (TextView) rRow.findViewById(R.id.text1);
        final String str = v.getText().toString().replaceFirst("\\s+$", "");

       If(str.equals(c.getString(0)){
       lL.setBackgroundColor(Color.Blue);
       }else{
       lL.setBackgroundColor(Color.Green);
       }


        vsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                Toast.makeText(MainActivity.this, str + "", Toast.LENGTH_SHORT).show();
            }
        });


        cb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cb.isChecked()) {
                    chkBox++;
                } else {
                    chkBox--;
                }
                if (chkBox > 1) {
                    editNoteSet.setVisibility(View.GONE);
                } else {
                    editNoteSet.setVisibility(View.VISIBLE);
                }
            }
        });

        return rRow;
    }
};
List.setAdapter(adapter);
kva1992
  • 103
  • 1
  • 11
  • Your tile question and your explanation is not match. – mr.icetea Dec 04 '15 at 03:18
  • How is it not a match? My issue was I couldn't change the background of the listview linearlayout from outside during the oncreate and running the code in the getview during the oncreate fixed the issue because I shouldn't be calling any view changes from outside the getView adapter because at that point there is no need to check if the layout is ready. The layout runs the code only after the layout is ready. So technically that is related because I was trying to set something outside the adapter which should have been set in the adapters getView statement. – kva1992 Dec 04 '15 at 08:09

2 Answers2

0

you should put this code in getView() in SimpleAdapter Here is what you need to do :

LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.mylist, null,true);
rowView.setBackgroundColor(Color.BLUE);//You Can define your own color by using Color.argb()     

note that mylist is the name of xml layout that defines your list's content

Mehrdad
  • 180
  • 1
  • 13
  • I tried this it didn't make any difference. It didn't crash but the color did not change. And since the colors in each row may be different not sure if that would work. – kva1992 Dec 03 '15 at 01:56
  • @kva1992 the color of background in each row can be different ,you just have to pass it from SimpleAdapter and set it to rowView .try to apply code above to rRow and let me know – Mehrdad Dec 03 '15 at 02:24
  • 1
    I didn't exactly use the same method just changed the information within the simple adapter rather than outside the adapter.Thank you for steering me in the right direction – kva1992 Dec 03 '15 at 17:42
0

Try to call the function that changes the background inside OnGlobalLayoutListener

listView.getViewTreeObserver().addOnGlobalLayoutListener(
            new OnGlobalLayoutListener() {

                @SuppressLint("NewApi")
                @SuppressWarnings("deprecation")
                @Override
                public void onGlobalLayout() {
                    if (!Build.JELLY_BEAN_COMPATIBILITY) {
                        listView.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                    } else {
                        listView.getViewTreeObserver()
                                .removeOnGlobalLayoutListener(this);
                    }
                    yourFunctionHere();
                }
            });
}
mr.icetea
  • 2,607
  • 3
  • 24
  • 42
  • Ding!!!! Thank you soo much that worked. I still have another problem that persists how would I call this method from a button click then? And what is the code actually doing? Or better question why was the other code registering that the frame layout was null? – kva1992 Dec 03 '15 at 02:24
  • @kva1992 You don't need to call this method from a button click, simple call you change background instead. Why this code is working? Because when your `Activity` call `onCreate` your view are not drawn yet, so you need to use a `OnGlobalLayoutListener` to keep watching when the view are finish drawn, follow this post http://stackoverflow.com/questions/7733813/how-can-you-tell-when-a-layout-has-been-drawn. – mr.icetea Dec 03 '15 at 02:32
  • Ahhh soo the reason it was crashing is because the layout wasn't drawn? if so how was the onclick working? That part is still not making sense is it because the onclick is already created thus when i click onclick it has something drawn? if that is the case I was clicking the button and it was having the same issue when it came to the all section which is weird. – kva1992 Dec 03 '15 at 02:38
  • view.getViewTreeObserver() .removeOnGlobalLayoutListener(this); (what is this code doing i get its removing the listener so does that mean view is equal to my listview? – kva1992 Dec 03 '15 at 02:38
  • @kva1992 replace view to your listview – mr.icetea Dec 03 '15 at 02:39
  • Alright so I recently added the .removeOnGlobalLayoutListener(this) and I have the same issue as before. And when I dont remove the listener it keeps running in the background and crashes. any ideas on how I can fix this issue? Essentially I need to verify if the layout is ready for me to change the background everytime i click the button. – kva1992 Dec 03 '15 at 03:23