Categories
discuss

CursorAdapter bindView optimization

When overriding ArrayAdapter I know is correct using a pattern like this:

if(view != null){
   ...create new view setting fields from data 
}else
  return view; //reuse view

is correct too using this pattern with CursorAdapters? My problem is that I have a textcolor which can be red or blue according to a cursor field, so I don’t want any errors like a red color on a cell which has a field needing blue color. My bindView code is something like this:

if(c.getString(2).equals("red"))
      textView.setTextColor(<red here>);
   else
      textView.setTextColor(<blue here>);

if I reuse view can I be sure that red goes on red, while blue goes on blue?

Answer

In CursorAdapter, you get layout in newView and bind data in bindView. CursorAdapter already do reuse pattern in getView so you don’t have to do it again. Below is the original getView source code.

  public View getView(int position, View convertView, ViewGroup parent) {
    if (!mDataValid) {
        throw new IllegalStateException("this should only be called when the cursor is valid");
    }
    if (!mCursor.moveToPosition(position)) {
        throw new IllegalStateException("couldn't move cursor to position " + position);
    }
    View v;
    if (convertView == null) {
        v = newView(mContext, mCursor, parent);
    } else {
        v = convertView;
    }
    bindView(v, mContext, mCursor);
    return v;
}

If you want further optimization using ViewHolder Pattern here is example: Create tag in newView and retrieve in bindView

    public class TimeListAdapter extends CursorAdapter {
     private LayoutInflater inflater;
     private    static  class   ViewHolder  {
         int    nameIndex;
         int    timeIndex;
         TextView   name;
         TextView   time;
    }
  public TimeListAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
  this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  }
  @Override
  public void bindView(View view, Context context, Cursor cursor) {
         ViewHolder holder  =   (ViewHolder)    view.getTag();
         holder.name.setText(cursor.getString(holder.nameIndex));
         holder.time.setText(cursor.getString(holder.timeIndex));
  }
  @Override
  public View newView(Context context, Cursor cursor, ViewGroup  
  p parent) {
         View   view    =   inflater.inflate(R.layout.time_row, null);
         ViewHolder holder  =   new ViewHolder();
         holder.name    =   (TextView)  view.findViewById(R.id.task_name);
         holder.time    =   (TextView)  view.findViewById(R.id.task_time);
     holder.nameIndex   =   cursor.getColumnIndexOrThrow 
         (TaskProvider.Task.NAME);
         holder.timeIndex   =   cursor.getColumnIndexOrThrow    
         (TaskProvider.Task.DATE);
         view.setTag(holder);
    return view;
  }
}
Categories
discuss

android emulator sd card “your SD card is full”

i edited an existing emulator to have an sd card of size 9mb and i added a boolean in the hardware section to support sd card. when i start the app it says “your SD card is full”, what do?

Answer

First, try making the SD card larger – like, 100 MB – and restarting the emulator. The boolean in the hardware section, IIRC, triggers the preferred location for the application’s APK – internal memory or SD card. An APK of 9MB is not that uncommon.

Categories
discuss

Custom calendar view in Android

I’m building a custom calendar view for my android app that allows you to swipe between months. I’ve created custom calendar square views, which I’ve embedded into a custom calendar month view, and everything is working perfectly on the 1-month scale.

Unfortunately, now I’m stuck. I now want to embed my custom calendar month views into an infinite view pager, so that I can scroll forward and backward through the calendar indefinitely.

I’ve tried adapting this horizontal pager for infinite scrolling by using a simple trick. I hold an array of 3 of my calendar month views and update the list based on where the user scrolls to. Example…

  1. [July, August, September] (focus is on August, then user swipes to September)
  2. [July, August, September] (focus is now on September)
  3. [August, August, September] (shift August left by one, overwriting July)
  4. [August, September, September] (shift September left by one, overwriting August)
  5. [August, September, September] (set the view to the middle September, so we’re centered again)
  6. [August, September, October] (overwrite the 2nd September with the actual next month)

When I do this, though, there’s a noticeable flash on the screen when swiping to the next month.

Here’s the code for forward scrolling (note: backward scrolling has the same issue)

private void updateViewsForForwardScroll() {
    // Note: INDEX_PREV = 0; INDEX_CURR = 1; INDEX_NEXT = 2
    ((CalendarMonthView) getChildAt(INDEX_PREV)).showMonth(oneMonthPriorTo(currentMonth));
    ((CalendarMonthView) getChildAt(INDEX_CURR)).showMonth(currentMonth);
    setCurrentScreen(INDEX_CURR, false);
    ((CalendarMonthView) getChildAt(INDEX_NEXT)).showMonth(oneMonthAfter(currentMonth));
}

I think the problem is that setCurrentScreen() finishes before showMonth(currentMonth), so the view at INDEX_CURR is still updating when the screen is set. I tried solving that by using the following strategy instead…

  1. [July, August, September] (focus is on August, then user swipes to September)
  2. [July, August, September] (focus is now on September)
  3. [August, September] (remove July, but store it for recycling)
  4. [August, September, October] (recycle July to instead display October, and add the view)

I haven’t touched the currently focused view at all, but there’s still a flash! This time, the screen flashes from September, to August, then back to September.

So what am I doing wrong? Is there a way to do what I’m trying to do without the user knowing about it? If not, is there an existing class I can leverage?

(As a side question, is there any way I can customize the Android CalendarView visually? That would really solve all my problems…)

Thanks in advance!

Answer

I ended up getting it to work by extending FragmentStatePagerAdapter, and also integrating user113215’s suggestion. I didn’t go for truly infinite scrolling, but rather virtually infinite (i.e. 10,000 months, or 833 years). Here’s the bulk of my code:

public static class CalendarAdapter extends FragmentStatePagerAdapter {
    private static final int NUM_MONTHS = 10000;
    private static final int INDEX_EPOCH = NUM_MONTHS/2;
    private static final int MONTHS_PER_YEAR = 12;
    private static final Calendar calendarMonthEpoch = new GregorianCalendar(2012, Calendar.AUGUST, 1);

    // ...

    @Override
    public int getCount() {
        return NUM_MONTHS;
    }

    @Override
    public Fragment getItem(int position) {
        return CalendarMonthFragment.newInstance(calendarMonthAtPosition(position));
    }

    private static Calendar calendarMonthAtPosition(int position) {
        int offset = position - INDEX_EPOCH;
        Calendar calMonthAtPosition = (Calendar) calendarMonthEpoch.clone(); 
        calMonthAtPosition.add(Calendar.MONTH, offset % MONTHS_PER_YEAR);
        calMonthAtPosition.add(Calendar.YEAR, offset / MONTHS_PER_YEAR);

        return calMonthAtPosition;
    }

    // ...

}
Categories
discuss

Eclipse : how we take arguments for main when run

In Java, for a normal main method :

public static void main(String[] args){
    // code here
}

String[] args is used to take some parameters from command line. I can run this file from command prompt by :

javac filename.java
java filename -30

But, it takes more steps, and I must cd to this folder. (to long for each time). So, Does anyway to run this file with some arguments for main in Eclipse.

Thanks 🙂

Answer

In Eclipse you can set up a Run Configuration for the Java Application. Click on the green “play” button in the Launch toolbar (next to the bug icon which starts debugging).

Within that configuration, you can set the working directory and command line arguments – and even prompt the user for command line arguments when it’s run, using arguments like ${string_prompt:Foo}.

Categories
discuss

Is it safe to use email encoders? Or how is it safest to show email address?

Services like : http://www.wbwip.com/wbw/emailencoder.html encodes email to ASCII. Is it totally safe? Can spammers copy this code and decode it?

They can decode it, so how is it safest to show your email on the website? Probably by putting it in the image?

Answer

No, it is not safe at all. You are still exposing your email address on the page. Some dumb spiders will end confused, but those which are up to date will definitely be able to “decode” these entities quickly. The only solution is to… not expose email address at all. If you use contact form with recipients to be chosen by users, use IDs and dereference it in your code. If you need to show email – show image, but if anyone would like to have you address in their spam DB, then he can always put it by hand there.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..