private synchronized void makeAnimationWidgetViewSlide(
      AppWidgetManager appWidgetManager, int[] appWidgetId) {
    RemoteViews updateViews = buildWidgetUpdate(appWidgetId);
    String str =
        "hello1111111111111111111111111232222222222222233333333333333333344444444444444444444444444444444444444444444444444";
    /*
    String str = "";
    for (Article article : articles){
        str = str + article.title;
    }
    */

    updateViews.setTextViewText(R.id.text_in, str);
    updateViews.setTextViewText(R.id.text_out, str);

    float fontSize = 14;

    updateViews.setFloat(R.id.text_in, "setTextSize", fontSize);
    updateViews.setFloat(R.id.text_out, "setTextSize", fontSize);
    /*
    Resources r = getResources();
    int len = str.length();
    float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, fontSize*len, r.getDisplayMetrics());
    */
    // updateViews.setFloat(R.id.text_in, "setWidth", 100);
    // updateViews.setFloat(R.id.text_out, "setWidth", 100);

    // RemoteViews updateViews = buildWidgetUpdate(appWidgetId);
    Bitmap in_bmp, out_bmp;

    out_bmp = makeBitmap(layoutIdx == 0 ? 0 : 1);
    in_bmp = makeBitmap(layoutIdx == 0 ? 1 : 0);

    updateViews.setImageViewBitmap(R.id.Move_InImage, in_bmp);
    updateViews.setImageViewBitmap(R.id.Move_OutImage, out_bmp);

    for (int widgetId : appWidgetId) {
      appWidgetManager.updateAppWidget(widgetId, updateViews);
      // appWidgetManager.updateAppWidget(widgetId, updateViews2);
    }
  }
  /**
   * Update a single widget.
   *
   * @param context {@link Context}
   * @param appWidgetManager {@link AppWidgetManager}
   * @param appWidgetId id of widget
   */
  static void updateWidget(
      final Context context, final AppWidgetManager appWidgetManager, final int appWidgetId) {
    Log.d(TAG, "updateWidget(" + appWidgetId + ")");
    final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(context);
    final long pid = p.getLong(WIDGET_PLANID + appWidgetId, -1L);
    final boolean showShortname = p.getBoolean(WIDGET_SHORTNAME + appWidgetId, false);
    final boolean showCost = p.getBoolean(WIDGET_COST + appWidgetId, false);
    final boolean showBillPeriod = p.getBoolean(WIDGET_BILLPERIOD + appWidgetId, false);
    final boolean showIcon = p.getBoolean(WIDGET_ICON + appWidgetId, false);
    final boolean smallWidget = p.getBoolean(WIDGET_SMALL + appWidgetId, false);
    final Float statsTextSize =
        p.getFloat(WIDGET_STATS_TEXTSIZE + appWidgetId, StatsAppWidgetConfigure.DEFAULT_TEXTSIZE);
    final Float planTextSize =
        p.getFloat(WIDGET_PLAN_TEXTSIZE + appWidgetId, StatsAppWidgetConfigure.DEFAULT_TEXTSIZE);
    final int textColor =
        p.getInt(WIDGET_TEXTCOLOR + appWidgetId, StatsAppWidgetConfigure.DEFAULT_TEXTCOLOR);
    final int bgColor =
        p.getInt(WIDGET_BGCOLOR + appWidgetId, StatsAppWidgetConfigure.DEFAULT_BGCOLOR);
    Log.d(TAG, "planid: " + pid);
    final ContentResolver cr = context.getContentResolver();

    if (pid < 0L) {
      return;
    }
    final long ppid = DataProvider.Plans.getParent(cr, pid);
    long bid = -1L;
    String pname = null;
    float cpp = 0F;
    int ltype = DataProvider.LIMIT_TYPE_NONE;
    long limit = 0L;
    int ptype = -1;
    String where;
    int upc, upm, ups;
    boolean isMerger;
    String billdayWhere = null;
    Cursor cursor =
        cr.query(
            DataProvider.Plans.CONTENT_URI,
            DataProvider.Plans.PROJECTION,
            DataProvider.Plans.ID + " = ?",
            new String[] {String.valueOf(pid)},
            null);
    if (cursor.moveToFirst()) {
      if (showShortname) {
        pname = cursor.getString(DataProvider.Plans.INDEX_SHORTNAME);
      } else {
        pname = cursor.getString(DataProvider.Plans.INDEX_NAME);
      }
      ptype = cursor.getInt(DataProvider.Plans.INDEX_TYPE);
      bid = cursor.getLong(DataProvider.Plans.INDEX_BILLPERIOD_ID);
      ltype = cursor.getInt(DataProvider.Plans.INDEX_LIMIT_TYPE);
      limit =
          DataProvider.Plans.getLimit(ptype, ltype, cursor.getLong(DataProvider.Plans.INDEX_LIMIT));
      upc = cursor.getInt(DataProvider.Plans.INDEX_MIXED_UNITS_CALL);
      upm = cursor.getInt(DataProvider.Plans.INDEX_MIXED_UNITS_MMS);
      ups = cursor.getInt(DataProvider.Plans.INDEX_MIXED_UNITS_SMS);
      cpp = cursor.getFloat(DataProvider.Plans.INDEX_COST_PER_PLAN);

      final String s = cursor.getString(DataProvider.Plans.INDEX_MERGED_PLANS);
      where = DataProvider.Plans.parseMergerWhere(pid, s);
      if (s == null || s.length() == 0) {
        isMerger = false;
      } else {
        isMerger = true;
      }
    } else {
      return;
    }
    cursor.close();

    int bpos = 0;
    int bmax = -1;
    if (bid >= 0L) {
      cursor =
          cr.query(
              DataProvider.Plans.CONTENT_URI,
              DataProvider.Plans.PROJECTION,
              DataProvider.Plans.ID + " = ?",
              new String[] {String.valueOf(bid)},
              null);
      if (cursor.moveToFirst()) {
        final int bp = cursor.getInt(DataProvider.Plans.INDEX_BILLPERIOD);
        final long bday = cursor.getLong(DataProvider.Plans.INDEX_BILLDAY);
        billdayWhere = DataProvider.Plans.getBilldayWhere(bp, bday, null);
        if (showBillPeriod && bp != DataProvider.BILLPERIOD_INFINITE) {
          Calendar billDay = Calendar.getInstance();
          billDay.setTimeInMillis(bday);
          billDay = DataProvider.Plans.getBillDay(bp, billDay, null, false);
          final Calendar nextBillDay = DataProvider.Plans.getBillDay(bp, billDay, null, true);

          final long pr = billDay.getTimeInMillis() / CallMeter.MILLIS;
          final long nx =
              (nextBillDay.getTimeInMillis() // .
                      / CallMeter.MILLIS)
                  - pr;
          long nw = System.currentTimeMillis();
          nw = (nw / CallMeter.MILLIS) - pr;

          bmax = (int) nx;
          bpos = (int) nw;
        }
      }
      cursor.close();
    }
    Log.d(TAG, "bpos/bmax: " + bpos + "/" + bmax);
    billdayWhere = DbUtils.sqlAnd(billdayWhere, where);

    int used = 0;
    PlanStatus ps =
        PlanStatus.get(
            cr, billdayWhere, isMerger && ptype == DataProvider.TYPE_MIXED, upc, upm, ups);

    if (ps == null) {
      ps = new PlanStatus();
    } else {
      Log.d(TAG, "plan: " + pid);
      Log.d(TAG, "count: " + ps.count);
      Log.d(TAG, "cost: " + ps.cost);
      Log.d(TAG, "billedAmount: " + ps.billedAmount);
      used = DataProvider.Plans.getUsed(ptype, ltype, ps.billedAmount, ps.cost);
    }
    if (ppid >= 0L) {
      ps.cost = 0F;
    } else {
      ps.cost += cpp;
    }

    String stats =
        Plans.formatAmount(ptype, ps.billedAmount, p.getBoolean(Preferences.PREFS_SHOWHOURS, true));
    if (ptype == DataProvider.TYPE_CALL) {
      stats += " (" + ps.count + ")";
    }
    if (limit > 0) {
      stats += "\n" + (used * CallMeter.HUNDRET / limit) + "%";
    }
    if (showCost && ps.cost > 0F) {
      stats += "\n" + String.format(Preferences.getCurrencyFormat(context), ps.cost);
    }

    Log.d(TAG, "limit: " + limit);
    Log.d(TAG, "used: " + used);
    Log.d(TAG, "stats: " + stats);

    final int widgetLayout =
        smallWidget ? R.layout.stats_appwidget_small : R.layout.stats_appwidget;
    final RemoteViews views = new RemoteViews(context.getPackageName(), widgetLayout);
    views.setImageViewBitmap(R.id.widget_bg, getBackground(bgColor, bmax, bpos, limit, used));
    views.setTextViewText(R.id.plan, pname);
    views.setTextViewText(R.id.stats, stats);
    views.setFloat(R.id.plan, "setTextSize", planTextSize);
    views.setFloat(R.id.stats, "setTextSize", statsTextSize);
    views.setTextColor(R.id.plan, textColor);
    views.setTextColor(R.id.stats, textColor);
    views.setOnClickPendingIntent(
        R.id.widget, PendingIntent.getActivity(context, 0, new Intent(context, Plans.class), 0));
    if (showIcon) {
      views.setViewVisibility(R.id.widget_icon, android.view.View.VISIBLE);
      switch (ptype) {
        case DataProvider.TYPE_DATA:
          views.setImageViewResource(R.id.widget_icon, R.drawable.data);
          break;
        case DataProvider.TYPE_CALL:
          views.setImageViewResource(R.id.widget_icon, R.drawable.phone);
          break;
        case DataProvider.TYPE_SMS:
        case DataProvider.TYPE_MMS:
          views.setImageViewResource(R.id.widget_icon, R.drawable.message);
          break;
        case DataProvider.TYPE_MIXED:
          views.setImageViewResource(R.id.widget_icon, R.drawable.phone);
          break;
      }
    }

    appWidgetManager.updateAppWidget(appWidgetId, views);
  }
  private RemoteViews updateRemoteViews(Context context, int widgetId) {
    Setup setup = Setup.load(context, widgetId);

    long now = Calendar.getInstance().getTimeInMillis();
    int daysLeft = DateUtil.daysBetween(now, setup.targetDate);
    int weekDaysLeft = DateUtil.weekDaysBetween(now, setup.targetDate);
    int daysFromStart = DateUtil.daysBetween(setup.startDate, setup.targetDate);
    Log.d(getClass().getSimpleName(), daysLeft + "/" + weekDaysLeft + ", max=" + daysFromStart);

    RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);

    Bitmap backImage =
        BackgroundImageAdapter.createColoredBackground(
            context, setup.backgroundIndex, setup.alpha, backgroundResId);
    views.setImageViewBitmap(R.id.image_back, backImage);

    if (daysLeft > 0) {
      if (setup.showDays.showCalendarDays()) {
        views.setViewVisibility(R.id.text_calendar_days, View.VISIBLE);
        views.setTextViewText(R.id.text_calendar_days, daysLeft + "");
        views.setTextColor(R.id.text_calendar_days, Color.BLACK);
      } else {
        views.setViewVisibility(R.id.text_calendar_days, View.GONE);
      }

      if (setup.showDays.showWeekDays()) {
        views.setViewVisibility(R.id.text_week_days, View.VISIBLE);
        views.setTextViewText(R.id.text_week_days, weekDaysLeft + "");
        views.setTextColor(R.id.text_week_days, Color.rgb(100, 100, 100));
        if (setup.showDays == ShowDaysType.WEEK) {
          views.setFloat(R.id.text_week_days, "setTextSize", 26);
        } else {
          views.setFloat(R.id.text_week_days, "setTextSize", 16);
        }
      } else {
        views.setViewVisibility(R.id.text_week_days, View.GONE);
      }

      if (setup.showEventName) {
        views.setTextViewText(R.id.text_footer, setup.eventName);
      } else {
        if (daysLeft == 1) {
          views.setTextViewText(R.id.text_footer, context.getString(R.string.label_day_left));
        } else {
          views.setTextViewText(R.id.text_footer, context.getString(R.string.label_days_left));
        }
      }

      if (setup.showProgress) {
        views.setViewVisibility(R.id.layout_progress, View.VISIBLE);
        views.setProgressBar(R.id.progress_days, daysFromStart, daysFromStart - daysLeft, false);
      } else {
        views.setViewVisibility(R.id.layout_progress, View.GONE);
      }
    } else {
      views.setViewVisibility(R.id.text_week_days, View.GONE);
      views.setViewVisibility(R.id.layout_progress, View.GONE);

      // check how many days elapsed since the target date
      views.setViewVisibility(R.id.text_calendar_days, View.VISIBLE);
      int daysSince = DateUtil.daysBetween(setup.targetDate, now);
      views.setTextViewText(R.id.text_calendar_days, daysSince + "");

      if (daysSince > 0) {
        views.setTextColor(R.id.text_calendar_days, Color.GRAY); // in the past
      } else {
        views.setTextColor(R.id.text_calendar_days, Color.RED); // today
      }

      if (setup.showEventName) {
        views.setTextViewText(R.id.text_footer, setup.eventName);
      } else {
        if (daysSince <= 0) {
          views.setTextViewText(R.id.text_footer, context.getString(R.string.label_today));
        } else if (daysSince == 1) {
          views.setTextViewText(R.id.text_footer, context.getString(R.string.label_day_since));
        } else {
          views.setTextViewText(R.id.text_footer, context.getString(R.string.label_days_since));
        }
      }
    }

    // configure the click behavior of the widget
    Intent intent = new Intent(context, CountdownPreferences.class);
    // this causes each widget to have a unique PendingIntent
    Uri data = Uri.withAppendedPath(Uri.parse("peregin://widget/id/"), String.valueOf(widgetId));
    intent.setData(data);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
    PendingIntent pendingIntent =
        PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    views.setOnClickPendingIntent(R.id.counter_widget, pendingIntent);

    return views;
  }