Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Calendar and Calendar Adapter

I have a custom calendar, modified from the one seen here. On initial load it shows everything as it is suppose to.

However I have two issues.

1.) On the previous month button it goes from August to July as expected but it doesn't clear off all the images.

2.) Going from July to August it stays on July and rearranges the dates.

BaseAdapter:

public class CalendarAdapter extends BaseAdapter {
    private Context mContext;
    private java.util.Calendar month;
    public GregorianCalendar pmonth; // calendar instance for previous month
    public GregorianCalendar pmonthmaxset;
    private GregorianCalendar selectedDate;
    public static List<String> dayString;
    private List<String[]> anArrayOfStrings = new ArrayList<String[]>();
    int firstDay, maxWeeknumber, maxP, calMaxP, lastWeekDay, leftDays, mnthlength;
    String itemvalue, curentDateString;
    DateFormat df;
    ImageView mimgPeriod, mimgEnergy, mimgIntercorse, mimgPregancy, mimgHeadache, mimgMood;
    DateFormat formatter;
    Date rowdatetemp;
    Date caldatetemp;
    String box;
    private int mHeight = 0;
    private int mWidth = 0;

    public CalendarAdapter(Context c, GregorianCalendar monthCalendar) {
        CalendarAdapter.dayString = new ArrayList<String>();
        Locale.setDefault( Locale.US );
        month = monthCalendar;
        selectedDate = (GregorianCalendar) monthCalendar.clone();
        mContext = c;
        month.set(GregorianCalendar.DAY_OF_MONTH, 1);
        new ArrayList<String>();
        df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
        curentDateString = df.format(selectedDate.getTime());
        refreshDays();
        box = null;

    }

    public void setItems(List<String[]> anArrayOfStrings) {
        this.anArrayOfStrings = anArrayOfStrings;
    }

    public int getCount() {
        return dayString.size();
    }

    public Object getItem(int position) {
        return dayString.get(position);
    }

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

    // create a new view for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        TextView dayView;

        if (convertView == null) { // if it's not recycled, initialize some
                                    // attributes
            LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.calendar_item, null);
        }

        dayView = (TextView) v.findViewById(R.id.date);

        // separates daystring into parts.
        String[] separatedTime = dayString.get(position).split("-");

        // taking last part of date. ie; 2 from 2012-12-02
        String gridvalue = separatedTime[2].replaceFirst("^0*", "");

        // checking whether the day is in current month or not.
        if ((Integer.parseInt(gridvalue) > 1) && (position < firstDay)) {
            // setting offdays to white color.
            dayView.setTextColor(Color.WHITE);
            dayView.setClickable(false);
            dayView.setFocusable(false);
        } else if ((Integer.parseInt(gridvalue) < 7) && (position > 28)) {
            dayView.setTextColor(Color.WHITE);
            dayView.setClickable(false);
            dayView.setFocusable(false);
        } else {
            // setting curent month's days in blue color.
            dayView.setTextColor(Color.BLUE);
        }

        dayView.setText(gridvalue);

        //create date string for comparison
        String date = dayString.get(position);

        if (date.length() == 1) {
            date = "0" + date;
        }

        String monthStr = "" + (month.get(GregorianCalendar.MONTH) + 1);
        if (monthStr.length() == 1) {
            monthStr = "0" + monthStr;
        }

        //look in the hashtable in order to find the position date and then populate the img's
        if ((anArrayOfStrings != null) && (anArrayOfStrings.size() > 0)) {
            if (formatter == null) {
                formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
            }
            Log.i("PROJECTCARUSO","Date: " + date);
            for (String[] row : anArrayOfStrings) {
                //convert date's
                try {
                    caldatetemp = (Date)formatter.parse(date); 
                } catch (ParseException e) {
                    e.printStackTrace();
                }

                try {
                    rowdatetemp = (Date)formatter.parse(row[0]); 
                } catch (ParseException e) {
                    e.printStackTrace();
                }

                // current position date in calendar
                // array date is after the calendar date
                if (rowdatetemp.after(caldatetemp)) {
                    break;
                //current position date > first array date then continue to see if there is one for this date
                } else if (rowdatetemp.before(caldatetemp)) {
                    continue;
                //Found a match
                } else if (date.equalsIgnoreCase(row[0])) { 
                    for (int i = 1; i < row.length; i++) {
                        Log.i("PROJECTCARUSO","row[" + i +"]: " + row[i]);

                        //Now that we have a match look through each detail
                        if ( row[i]!= null ) {
                                if ((i == 1) && ((row[i].equalsIgnoreCase("yes")) || (isNumeric(row[i]))))  {
                                    mimgPeriod      = (ImageView) v.findViewById(R.id.imgPeriod);
                                    setVisible(v, mimgPeriod);
                                    mimgPeriod.setImageAlpha(100);
                                    box = "red";
                                    continue; 
                                }

                                if ((i == 2) && ((row[i].equalsIgnoreCase("yes")) || (isNumeric(row[i])))) {
                                    mimgIntercorse  = (ImageView) v.findViewById(R.id.imgIntercorse);
                                    setVisible(v, mimgIntercorse);
                                    mimgIntercorse.setImageAlpha(100);
                                    continue; 
                                }

                                if ((i == 4) && ((row[i].equalsIgnoreCase("yes")) || (isNumeric(row[i])))) {
                                    mimgHeadache    = (ImageView) v.findViewById(R.id.imgHeadache);
                                    setVisible(v, mimgHeadache);
                                    mimgHeadache.setImageAlpha(100);
                                    continue; 
                                }

                                if ((i == 5) && ((row[i].equalsIgnoreCase("yes")) || (isNumeric(row[i])))) {
                                    mimgPregancy    = (ImageView) v.findViewById(R.id.imgPregancy);
                                    setVisible(v, mimgPregancy);
                                    mimgPregancy.setImageAlpha(100);
                                    continue; 
                                }
                        }

                        if (( row[i]!= null ) && (i == 6) && (!row[i].equalsIgnoreCase("no"))) {
                            mimgEnergy      = (ImageView) v.findViewById(R.id.imgEnergy);
                            setImg(v, mimgEnergy, row[i].toString());
                            setVisible(v, mimgEnergy);
                            continue; 
                        }

                        if (( row[i]!= null ) && (i == 3) && (!row[i].equalsIgnoreCase("no"))) {
                            mimgMood        = (ImageView) v.findViewById(R.id.imgMood);
                            setImg(v, mimgMood, row[i].toString());
                            setVisible(v, mimgMood);
                            continue; 
                        }

                        if (( row[i]!= null ) && (i == 7) || (box != null)) {

                            if (box == null) {
                                if (row[i].equalsIgnoreCase("no")) {
                                    box = "brown";

                                } else {
                                    box = "yellow";
                                }
                            }

                            Drawable []layers = new Drawable [2];
                            int imageResource1 = mContext.getResources().getIdentifier("drawable/calendar_cell", null, mContext.getPackageName());
                            Drawable background = v.getResources().getDrawable(imageResource1);
                            layers [0]= background;

                            int imageResource = mContext.getResources().getIdentifier("drawable/box_" + box, null, mContext.getPackageName());
                            Drawable boxImg = v.getResources().getDrawable(imageResource);
                            boxImg.setAlpha(100);
                            layers [1]= boxImg;

                            LayerDrawable layerDrawable = new LayerDrawable (layers);

                            mWidth = v.getWidth();
                            mHeight=v.getHeight();
                            v.getLayoutParams().height = mHeight;
                            v.getLayoutParams().width = mWidth;
                            v.setBackground(layerDrawable);

                            //reset
                            box = null;

                            continue; 
                        }
                    }
                } else {
                    break;
                }
            }
        } else {
            Log.i("PROJECTCARUSO","RESETING VIEWS TO INVISIBLE");
            mimgMood        = (ImageView) v.findViewById(R.id.imgMood);
            mimgEnergy      = (ImageView) v.findViewById(R.id.imgEnergy);
            mimgPregancy    = (ImageView) v.findViewById(R.id.imgPregancy);
            mimgHeadache    = (ImageView) v.findViewById(R.id.imgHeadache);
            mimgIntercorse  = (ImageView) v.findViewById(R.id.imgIntercorse);
            mimgPeriod      = (ImageView) v.findViewById(R.id.imgPeriod);
            setInvisibleVisible(v, mimgMood);
            setInvisibleVisible(v, mimgEnergy);
            setInvisibleVisible(v, mimgPregancy);
            setInvisibleVisible(v, mimgHeadache);
            setInvisibleVisible(v, mimgIntercorse);
            setInvisibleVisible(v, mimgPeriod);
        }

        //clear the array after using it.
        //anArrayOfStrings.clear();
        return v;       
    }

    public View setVisible(View view, ImageView iv) {
        iv.setVisibility(View.VISIBLE);
        return view;
    }

    public View setInvisibleVisible(View view, ImageView iv) {
        iv.setVisibility(View.INVISIBLE);
        return view;
    }

    public View setImg(View view, ImageView iv, String mood) {
        iv.setImageAlpha(100);
        iv.setVisibility(View.VISIBLE);
        int draw = mContext.getResources().getIdentifier("drawable/" + mood, null, mContext.getPackageName()); 
        iv.setImageResource(draw);
        return view;
    }

    public void refreshDays() {
        // clear items
        anArrayOfStrings.clear();

        dayString.clear();
        Locale.setDefault( Locale.US );
        pmonth = (GregorianCalendar) month.clone();

        // month start day. ie; sun, mon, etc
        firstDay = month.get(GregorianCalendar.DAY_OF_WEEK);

        // finding number of weeks in current month.
        maxWeeknumber = month.getActualMaximum(GregorianCalendar.WEEK_OF_MONTH);

        // allocating maximum row number for the gridview.
        mnthlength = maxWeeknumber * 7;
        maxP = getMaxP(); // previous month maximum day 31,30....
        calMaxP = maxP - (firstDay - 1);// calendar offday starting 24,25 ...

        pmonthmaxset = (GregorianCalendar) pmonth.clone();
        pmonthmaxset.set(GregorianCalendar.DAY_OF_MONTH, calMaxP + 1);

        for (int n = 0; n < mnthlength; n++) {

            itemvalue = df.format(pmonthmaxset.getTime());
            pmonthmaxset.add(GregorianCalendar.DATE, 1);
            dayString.add(itemvalue);

        }
    }

    private int getMaxP() {
        int maxP;
        if (month.get(GregorianCalendar.MONTH) == month
                .getActualMinimum(GregorianCalendar.MONTH)) {
            pmonth.set((month.get(GregorianCalendar.YEAR) - 1),
                    month.getActualMaximum(GregorianCalendar.MONTH), 1);
        } else {
            pmonth.set(GregorianCalendar.MONTH,
                    month.get(GregorianCalendar.MONTH) - 1);
        }
        maxP = pmonth.getActualMaximum(GregorianCalendar.DAY_OF_MONTH);

        return maxP;
    }

    @SuppressWarnings("unused")
    public static boolean isNumeric(String str)  
    {  
      try  
      {  
        double d = Double.parseDouble(str);  
      }  
      catch(NumberFormatException nfe)  
      {  
        return false;  
      }  
      return true;  
    }

}

Calendar:

public class CalendarFragment extends Fragment {

    public GregorianCalendar month;// calendar instances.
    public CalendarAdapter adapter;           // adapter instance
    public Handler handler;                   // for grabbing some event values for showing the dot
                                              // marker.
    public ArrayList<String> items;           // container to store calendar items which
                                              // needs showing the event marker
    int i;
    List<String[]> anArrayOfStrings = new ArrayList<String[]>();
    String startdate, enddate;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }     

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {     
        View view = inflater.inflate(R.layout.fragment_calendar, null);

        month = (GregorianCalendar) GregorianCalendar.getInstance();
        month.set(Calendar.DAY_OF_MONTH, 1-1);

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd",Locale.US);

        //start date for cursor
        startdate = df.format(month.getTime());

        //end date
        month.add(Calendar.MONTH, 1);
        month.add(Calendar.DAY_OF_MONTH, +5);
        enddate = df.format(month.getTime());

        month.add(Calendar.MONTH, -1);
        Locale.setDefault( Locale.US );
        month = (GregorianCalendar) GregorianCalendar.getInstance();

        items = new ArrayList<String>();
        adapter = new CalendarAdapter(getActivity(), month);

        GridView gridview = (GridView) view.findViewById(R.id.gridview);
        gridview.setAdapter(adapter);

        handler = new Handler();
        handler.post(calendarUpdater);

        TextView title = (TextView) view.findViewById(R.id.title);
        title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));

        RelativeLayout previous = (RelativeLayout) view.findViewById(R.id.previous);

        previous.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                setPreviousMonth();
                refreshCalendar();
            }
        });

        RelativeLayout next = (RelativeLayout) view.findViewById(R.id.next);
        next.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                setNextMonth();
                refreshCalendar();

            }
        });

        gridview.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                    int position, long id) {

                String selectedGridDate = CalendarAdapter.dayString
                        .get(position);
                String[] separatedTime = selectedGridDate.split("-");
                String gridvalueString = separatedTime[2].replaceFirst("^0*",
                        "");// taking last part of date. ie; 2 from 2012-12-02.
                int gridvalue = Integer.parseInt(gridvalueString);
                // navigate to next or previous month on clicking offdays.
                if ((gridvalue > 10) && (position < 8)) {
                    setPreviousMonth();
                    refreshCalendar();
                } else if ((gridvalue < 7) && (position > 28)) {
                    setNextMonth();
                    refreshCalendar();
                }
            }
        });
        return view;
    }

    protected void setNextMonth() {
        if (month.get(GregorianCalendar.MONTH) == month
                .getActualMaximum(GregorianCalendar.MONTH)) {
            month.set((month.get(GregorianCalendar.YEAR) + 1),
                    month.getActualMinimum(GregorianCalendar.MONTH), 1);
        } else {
            month.set(GregorianCalendar.MONTH,
                    month.get(GregorianCalendar.MONTH) + 1);
        }

    }

    protected void setPreviousMonth() {
        if (month.get(GregorianCalendar.MONTH) == month
                .getActualMinimum(GregorianCalendar.MONTH)) {
            month.set((month.get(GregorianCalendar.YEAR) - 1),
                    month.getActualMaximum(GregorianCalendar.MONTH), 1);
        } else {
            month.set(GregorianCalendar.MONTH,
                    month.get(GregorianCalendar.MONTH) - 1);
        }

    }

    public void refreshCalendar() {
        TextView title = (TextView) getActivity().findViewById(R.id.title);

        adapter.refreshDays();
        adapter.notifyDataSetChanged();
        handler.post(calendarUpdater); // generate some calendar items

        title.setText(android.text.format.DateFormat.format("MMMM yyyy", month));
    }

    public Runnable calendarUpdater = new Runnable() {

        @Override
        public void run() {

            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd",Locale.US);

            //start date for cursor
            month.add(Calendar.DAY_OF_MONTH, -1);
            startdate = df.format(month.getTime());

            //end date
            month.add(Calendar.MONTH, 1);
            enddate = df.format(month.getTime());
            month.add(Calendar.MONTH, -1);

            anArrayOfStrings.clear();

            // Get the data
            Cursor c = getActivity().getContentResolver().query(StatusProvider.CONTENT_URI_CHARTING, null, "? < " + StatusData.KEY_CHARTING_DATE + " AND ? > " + StatusData.KEY_CHARTING_DATE , new String[] {startdate, enddate}, StatusData.KEY_CHARTING_DATE + " ASC");
            c.moveToFirst();
            while(c.isAfterLast() == false){
                anArrayOfStrings.add( new String [] {c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_DATE)),
                                              c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_PERIOD)), c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_INTERCORSE)), 
                                              c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_MOOD)), c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_HEADACHE)), 
                                              c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_TEST)), c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_ENERGY)),
                                              c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_FERTILE) )});


                Log.i("PROJECTCARUSO","DATE ADDED TO ARRAY:" +  c.getString(c.getColumnIndex(StatusData.KEY_CHARTING_DATE)));

                i+=1;
                c.moveToNext();
            } 

            adapter.setItems(anArrayOfStrings);
            adapter.notifyDataSetChanged();
        }
    };

}

Calendar_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/calendar_cell"
    android:orientation="vertical" >

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

        <TextView
            android:id="@+id/date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"
            android:textColor="#0000D7"
            android:textSize="14sp"
            android:textStyle="bold" />

    </LinearLayout>

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

        <ImageView
            android:id="@+id/imgPeriod"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/period"  
            android:visibility="invisible"/>

        <ImageView
            android:id="@+id/imgIntercorse"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/intercorse"
            android:visibility="invisible" />

        <ImageView
            android:id="@+id/imgPregancy"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/pregnancy"
            android:visibility="invisible"  />
    </LinearLayout>


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

        <ImageView
            android:id="@+id/imgEnergy"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/energy_1"
            android:visibility="invisible" />

        <ImageView
            android:id="@+id/imgHeadache"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/pregnancy"
            android:visibility="invisible" />

        <ImageView
            android:id="@+id/imgMood"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:src="@drawable/mood"
            android:visibility="invisible" />
     </LinearLayout>

</LinearLayout>

fragment_calendar.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/background"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/calendar_top" >

        <RelativeLayout
            android:id="@+id/previous"
            android:layout_width="40dip"
            android:layout_height="30dip"
            android:layout_alignParentLeft="true" >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:background="@drawable/arrow_left" />
        </RelativeLayout>

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="5dip"
            android:textColor="#000000"
            android:textSize="18dip"
            android:textStyle="bold" />

        <RelativeLayout
            android:id="@+id/next"
            android:layout_width="40dip"
            android:layout_height="30dip"
            android:layout_alignParentRight="true" >

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:background="@drawable/arrow_right" />
        </RelativeLayout>
    </RelativeLayout>

    <GridView
        android:id="@+id/gridview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:listSelector="@android:color/transparent"
        android:numColumns="7"
        android:stretchMode="columnWidth" />

</LinearLayout>
like image 536
jcaruso Avatar asked Jul 26 '13 19:07

jcaruso


1 Answers

1st fix: I'm not resetting the background. So this fixes that part. Now the views (dates) are not getting repopulated when going previous month.

//set background
int imageResource = mContext.getResources().getIdentifier("drawable/calendar_cell", null, mContext.getPackageName());
Drawable orgImg = v.getResources().getDrawable(imageResource);
v.setBackground(orgImg);

2nd fix: Reusing the calendar object is throwing off your calendar. Create a new calendar object so they don't conflict with each other.

like image 120
jcaruso Avatar answered Sep 21 '22 16:09

jcaruso