Muzei live wallpaper is a new opensource project from Roman Nurik which provide a nice API for other developers to build extension on it easily. Just a few days after its release on Feb 12, you can already find quite many different data source for it. So I played for a while today and found that it is… really easy to implement your own data source.
Here is a quick start on creating the extension.
1234567891011121314151617181920212223242526272829
publicclassMyArtSourceextendsRemoteMuzeiArtSource{privatestaticfinalintUPDATE_INTERVAL=60*60*1000;// 60minpublicMyArtSource(){super("my-art-source");}@OverridepublicvoidonCreate(){super.onCreate();setUserCommands(BUILTIN_COMMAND_ID_NEXT_ARTWORK);// manual switch image}@OverrideprotectedvoidonTryUpdate(intreason)throwsRetryException{// fetch title, imageUrl, id, url from remote or hardcodepublishArtwork(newArtwork.Builder().title(title).imageUri(Uri.parse(imageUrl)).token(id).viewIntent(newIntent(Intent.ACTION_VIEW,Uri.parse(url))).build());scheduleUpdate(System.currentTimeMillis()+UPDATE_INTERVAL);// switch image after 60min}}
You can find my Muzei 9GAG extension on Play store, source code available on Github
Last year I implemented a custom view that supports different gestures including zoom(scale), scroll, double tap. As a newbie on custom view, the whole measuring and drawing already spent me some time, so the gesture control turned out enough to use but was actually incomplete and not finished.
Recently, I have a task to embed my custom view to ViewPager and other custom ViewGroup that intercept touch events. As expected, my custom view takes all the touch events so the ViewPager cannot perform horizontal swipe. I woule like to take this chance to review my gesture handling and hopefully can make it work.
What I did last year is mostly referencing Chris Banes’s PhotoView library. The basic idea is:
create a “view attacher” that implements a View.OnTouchListener
use those detectors in OnTouchListener’s onTouch method
1234567891011121314151617181920212223
publicclassZoomableViewAttacherimplementsView.OnTouchListener{GestureDetectormGestureDetector;ScaleGestureDetectormScaleGestureDetector;...@OverridepublicfinalbooleanonTouch(Viewv,MotionEventev){booleanhandled=false;...if(null!=mGestureDetector&&mGestureDetector.onTouchEvent(ev)){handled=true;}if(null!=mScaleGestureDetector&&mScaleGestureDetector.onTouchEvent(ev)){handled=true;}returnhandled;// or just return true;}}
So far this worked for me last year as I am using the view alone, I did not have to consider the case that the view’s parent intercepted the touch event.
Now the problem is, how do I prevent the ViewPager intercepting my touch event? After digging deeper, I found a requestDisallowInterceptTouchEvent method in ViewParent. According to the framework doc
Called when a child does not want this parent and its ancestors to intercept touch events with onInterceptTouchEvent(MotionEvent).
This parent should pass this call onto its parents. This parent must obey this request for the duration of the touch (that is, only clear the flag after this parent has received an up or a cancel.
Which means, if I call the method in correct time, I should be able to enable and disable ViewPager’s onInterceptTouchEvent. Googled a little bit on requestDisallowInterceptTouchEvent, found some example on StackOverflow like
This is obviously not enough for me, since it disabled the parent for the whole touch motion, if I touch on my custom and actually want to perform a page swipe on ViewPager, thie code will definitely break the ViewPager usage.
It would be great if GestureDetector can directly give me the information needed for my canScroll() method. However, it seems that GestureDetector need a few events to determine if it is a scroll, there is a gap of 3-5 events between my first ACTION_DOWN and onScoll callback, so I need a better way to determine the condition for calling parent.requestDisallowInterceptTouchEvent().
In part 2, I will continue with the implementation of canScroll() method.
Michael Marucheck, had the idea to actually edit the Java byte code after compilation. We used ASM to improve our dependency injection system by detecting bindings that are safe to remove, adding static methods that instantiate a bound type, and rewriting calls to the injector to instead call the appropriate static method. By improving this process, we were able to have a well-crafted dependency injection system that lets us test at scale, but still with the 30% gain in speed.
2013 was a fresh start for me. I joined a new team, started the Android product from scratch, get a nice number of active users and keep it growing. During my development, I referenced many opensource projects and learnt alot from them.
This is the very first library I added to my project (support-v4 does not count). This library provided a nice wrap of http call. I am not sure if this can be used with other network library like square/okhttp and android/volley, hope I have time to try it out in 2014.
This is the sliding menu I used at the beginning, I like the effect very much. Although I switched to Android DrawerLayout after it was introduced in support-v4, I do like the old SlidingMenu more. Personally I like to have the drawer push the content out, DrawerLayout is more like an overlay, they both make sense to me, let see will the design guideline include this kind of UI also.
I am a big fan of Square opensource projects but I was not using any event bus so when I saw otto I did not get it at first. When things getting complicated that you cannot write everything in your Activity/Fragment, you will try to split the logic to different components. The old school way to communicate between components is implements some kind of listener, it works for a while, a short while… The app goes complicated way faster than I expect, so I decided to make a big structure change by using an event bus system. I have not compared other event bus library but otto works for me perfectly.
ActionBar
Before the official actionbar-compact was released after GoogleIO, I think most people will use ActionBarSherlock. However, I implmented my own. I think it gives me more flexibility if you implemented your own, especially when you dont need those inflate from menu support. The down side is you lost support from all opensource projects, I have to implement my own refresh/progress buttons, ShareActionProvider, cannot play with those fancy fading actionbar, not boring actionbar library, may even need to write my own android style pull to refresh. Those disadvantage are usually enough to stop me from using my own implementation, but I decided to keep it. Mostly because it turns out not that hard to migrate to my own actionbar as long as it is opensourced and I do not have to worry about two libraries not working together (because I am not using any…).