Using RecyclerView Instead Of ViewPager For Gallery

Phimpme is an Image app that provide camera, editing ,sharing options and a gallery section. The Gallery section allows us to view large number of images that are locally available in the users device. Generally developers used viewpager to swipe the horizontal images although we are also using viewPager but the problem is it is taking more time to load large size images and that disturb the user smooth experience. After so much research I came to new solution. So in this post, I will be explaining how to use recyclerview to view gallery images instead of viewPager. Let’s get started Make sure you have Recyclerview support in your dependencies in build.gradle. As recyclerView required an adapter and viewHolder to set data in recyclerView. So I will be explaining about adapter. ViewHolder for RecyclerView public static class ViewHolder extends RecyclerView.ViewHolder {   ImageView imageView;   LinearLayout linearLayout;   public ViewHolder(View itemView) {       super(itemView);       imageView = new ImageView(context);       linearLayout = (LinearLayout) itemView.findViewById(R.id.layout);       WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);       Display display = wm.getDefaultDisplay();       Point size = new Point();       display.getSize(size);       int width = size.x;       int height = size.y;       LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(               width, height);       imageView.setLayoutParams(params);       imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);       linearLayout.addView(imageView);   } } Right now the imageView is adjusting according to device screen size so that it will be compatible with all devices. I am passing the width and height in LayoutParams to parent of imageview i.e in our case linearlayout is parentView. Adapter for RecyclerView public ImageAdapter(ArrayList<Media> media) {   this.media = media; } @Override public ImageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {   View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.unit_image_pager, null, false);   return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, int position) {   Glide.with(getContext())           .load(media.get(position).getUri())           .diskCacheStrategy(DiskCacheStrategy.SOURCE)           .thumbnail(0.5f)           .into(holder.imageView);   holder.imageView.setOnClickListener(new View.OnClickListener() {       @Override       public void onClick(View v) {           basicCallBack.callBack(0,null);       }   }); } MediaList is an arrray of media that contains the list of images with URI that will help to load images. I am using Glide to load images you can use any library to load images. Adapter helps to load data in recyclerView. Now set viewPager where you require to scroll images horizontally @Nullable @BindView(R.id.photos_pager) RecyclerView mRecylerPager; mRecylerPager.setLayoutManager(linearLayoutManager); mRecylerPager.setHasFixedSize(true); mRecylerPager.setLongClickable(true); Our recycler view is ready now the most important part is to set things onPageChangeListner. For example : In Phimpme we are getting path of current position image to show in image description so to update the value we are writing that codde in onPageChangeListner and to update the toolbar. mViewPager.setOnPageChangeListener(new PagerRecyclerView.OnPageChangeListener() {   @Override   public void onPageChanged(int oldPosition, int position) {       getAlbum().setCurrentPhotoIndex(position);       toolbar.setTitle((position + 1) + " " + getString(R.string.of) + " " + size_all);       invalidateOptionsMenu();       pathForDescription = getAlbum().getMedia().get(position).getPath();   } }); To scroll to the given position we require to set the position to recyclerView and it can be done by the following code mViewPager.scrollToPosition(getCurrentPsotion()); This is how I implemented the recyclerView instead of ViewPager to load gallery images faster as compare to ViewPager. RecyclerView in Phimpme to load gallery Images Resources:      RecylerView official documentation: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html ViewPager official documentation: https://developer.android.com/reference/android/support/v4/view/ViewPager.html Basic RecyclerView Tutorial: https://www.raywenderlich.com/126528/android-recyclerview-tutoria  

Continue ReadingUsing RecyclerView Instead Of ViewPager For Gallery

Implementing Tweet Search feature in Loklak Wok Android

Loklak Wok Android is a peer harvester that posts collected tweets to the Loklak Server. Along with that tweets can be searched using the app. This post describes how search API endpoint and TabLayout is used to implement the tweet searching feature. Adding Dependencies to the project This feature uses Retrofit2, Reactive extensions(RxJava2, RxAndroid and Retrofit RxJava adapter) and RetroLambda (for Java lambda support in Android). In app/build.gradle: apply plugin: 'com.android.application' apply plugin: 'me.tatarka.retrolambda' android { ... packagingOptions { exclude 'META-INF/rxjava.properties' } } dependencies { ... compile 'com.google.code.gson:gson:2.8.1' compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' compile 'io.reactivex.rxjava2:rxjava:2.0.5' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' }   In build.gradle project level: dependencies { classpath 'com.android.tools.build:gradle:2.3.3' classpath 'me.tatarka:gradle-retrolambda:3.2.0' }   Implementation The search API endpoint is defined in LoklakApi interface which would provide the tweet search result. public interface LoklakApi { @GET("api/search.json") Observable<Search> getSearchedTweets( @Query("q") String query, @Query("filter") String filter, @Query("count") int count); }   The POJOs (Plain Old Java Objects) for the result of search API endpoint are obtained using jsonschema2pojo, Gson uses POJOs to convert JSON to Java objects and vice-versa. The REST client is created by Retrofit2 and is implemented in RestClient class. The Gson converter and RxJava adapter for retrofit is added in the retrofit builder. create method is called to generate the API methods(retrofit implements LoklakApi Interface). public class RestClient { private RestClient() { } private static void createRestClient() { sRetrofit = new Retrofit.Builder() .baseUrl(BASE_URL) // gson converter .addConverterFactory(GsonConverterFactory.create(gson)) // retrofit adapter for rxjava .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); } private static Retrofit getRetrofitInstance() { if (sRetrofit == null) { createRestClient(); } return sRetrofit; } public static <T> T createApi(Class<T> apiInterface) { // create method to generate API methods return getRetrofitInstance().create(apiInterface); } }   As search API endpoint provides filter parameter which can be used to filter out tweets containing images and videos. So, the tweets are displayed in three categories i.e. latest, images and videos. The tweets of different category are displayed using a ViewPager. The fragments in ViewPager are inflated by a class that extends FragmentPagerAdapter. SearchFragmentPagerAdapter extends FragmentPagerAdapter, at least two methods getItem and getCount needs to be overridden. Going by the name of methods, getItem provides ith fragment to the  ViewPager and based on the value returned by getCount number of tabs are inflated in TabLayout, a ViewGroup to display fragments in ViewPager in an elegant way. For better UI, the names (here the category of tweets) are displayed, for which we override getPageTitle method. public class SearchFragmentPagerAdapter extends FragmentPagerAdapter { private List<Fragment> mFragmentList = new ArrayList<>(); private List<String> mFragmentNameList = new ArrayList<>(); public SearchFragmentPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } @Override public CharSequence getPageTitle(int position) { return mFragmentNameList.get(position); } public void addFragment(Fragment fragment, String pageTitle) { mFragmentList.add(fragment); mFragmentNameList.add(pageTitle); } }   For easy understanding an analogy with RecyclerView can be made. The TabLayout here functions as a RecyclerView, ViewPager does the work of LayoutManager and FragmentPagerAdapter is analogous to RecyclerView.Adapter. Now, the fragments which contain the…

Continue ReadingImplementing Tweet Search feature in Loklak Wok Android