Showing posts with label Lollipop. Show all posts
Showing posts with label Lollipop. Show all posts

Last Updated: October 14, 2015

Android Multiple row layout using RecyclerView

Description: In this post I'm gonna show you how we can have multiple row layout in Android's Material Design  RecyclerView  using   getItemViewType.

compile 'com.android.support:cardview-v7:23.0.0'
compile 'com.android.support:recyclerview-v7:23.0.0'

GitHub Project HERE

So lets get started :-)



Step 1:
Create Recycler Adapter by overriding getItemViewType method and giving the type for different layout as shown below.


@Override

public int getItemViewType(int position) {

    MultipleRowModel multipleRowModel = multipleRowModelList.get(position);

    if (multipleRowModel != null)
        return multipleRowMod.type;

    return super.getItemViewType(position);
}
Step 2: Create a viewHolder as per viewType .  We can create different row layout using viewType .

Note: viewType in onCreateviewholder is retured from getItemViewType in Step 1.
@Override
public MultipleRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = null;

    if (viewType == AppConstant.FIRST_ROW)
        view = inflater.inflate(R.layout.view_row_first, parent, false);
    else if (viewType == AppConstant.OTHER_ROW)
        view = inflater.inflate(R.layout.view_row_other, parent, false);

    return new MultipleRowViewHolder(view, viewType);
}

Step 3: Lets integrated all this in one RecyclerView adapter.

public class MultipleRowAdapter extends RecyclerView.Adapter<MultipleRowViewHolder> {

    private LayoutInflater inflater = null;
    private List<MultipleRowModel> multipleRowModelList;

    public MultipleRowAdapter(Context context, List<MultipleRowModel> multipleRowModelList){
        this.multipleRowModelList = multipleRowModelList;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public MultipleRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = null;

        if (viewType == AppConstant.FIRST_ROW)
            view = inflater.inflate(R.layout.view_row_first, parent, false);
        else if (viewType == AppConstant.OTHER_ROW)
            view = inflater.inflate(R.layout.view_row_other, parent, false);

        return new MultipleRowViewHolder(view, viewType);
    }

    @Override
    public void onBindViewHolder(MultipleRowViewHolder holder, int position) {
        holder.multipleContent.setText(multipleRowModelList.get(position).modelContent);
    }

    @Override
    public int getItemCount() {
        return (multipleRowModelList!= null && multipleRowModelList.size() > 0 ) ? multipleRowModelList.size() : 0;
    }

    @Override
    public int getItemViewType(int position) {

        MultipleRowModel multipleRowModel = multipleRowModelList.get(position);

        if (multipleRowModel != null)
            return multipleRowModel.type;

        return super.getItemViewType(position);
    }

}





Step 4: Finally our MainActivity looks something like this.

public class MainActivity extends AppCompatActivity {

    private RecyclerView multipleRowRecyclerView;
    private MultipleRowAdapter multipleRowAdapter;

    private List<MultipleRowModel> multipleRowModelList = new ArrayList<>();

    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        multipleRowRecyclerView = (RecyclerView)findViewById(R.id.multipleRowRecyclerView);
        multipleRowRecyclerView.setHasFixedSize(true);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, OrientationHelper.VERTICAL, false);
        multipleRowRecyclerView.setLayoutManager(linearLayoutManager);
        multipleRowRecyclerView.setItemAnimator(new DefaultItemAnimator());

        fillAdapter();

        multipleRowAdapter = new MultipleRowAdapter(MainActivity.this, multipleRowModelList);

        multipleRowRecyclerView.setAdapter(multipleRowAdapter);
    }

    private void fillAdapter() {

        int type;

        String content;

        for (int i = 0; i < 10; i++) {

            if (i == 0 || i == 5 || i == 9) {
                type = AppConstant.FIRST_ROW;
                content = "Type 1: This is Multiple row layout";
            } else {
                type = AppConstant.OTHER_ROW;
                content = "Type 2";
            }

            multipleRowModelList.add(new MultipleRowModel(type , content));
        }
    }
}


GitHub Project HERE

Sample Output :


Last Updated: May 26, 2015

Lollipop SwipeRefreshLayout with loader


Description: In this post I'm gonna show you how to use Lollipop's SwipeRefreshLayout using loader in android.It demostrate use of swipe refresh with loader's restartloader() method.

Github project for the same here


Step 1: Add the dependency in build.gradle
dependencies {
    compile 'com.android.support:appcompat-v7:21.0.2' // or your updated version
}
Step 2: Create Layout to use swipeRefreshLayout.It can be wrap over Scrollview or ListView.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/video_listView"
        android:layout_width="match_parent"
        android:smoothScrollbar="true"
        android:layout_height="match_parent" />

</android.support.v4.widget.SwipeRefreshLayout>


Step 3:Finally lets wrap everthing in code.

Note: Here loader is used  to fetch the videos names from phone and a swipeRefreshLayout functionality is added to update the content.

public class MainActivity extends FragmentActivity implements  LoaderManager.LoaderCallbacks<Cursor>  ,SwipeRefreshLayout.OnRefreshListener {

    private static final int LOADER_ID = 100;
    private ListView videoList;
    private SwipeRefreshLayout swipeContainer;
    private Context context;
    private SwipeAdapter swipeListAdapter;
    private String TAG = MainActivity.class.getName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        context         = MainActivity.this;
        videoList       = (ListView) findViewById(R.id.video_listView);
        swipeContainer  = (SwipeRefreshLayout) findViewById(R.id.swipe_container);


        swipeContainer.setColorSchemeResources(
                R.color.swiperedcolor,
                R.color.swipegreencolor,
                R.color.swipeyellowcolor,
                R.color.swipebluecolor);


        swipeListAdapter = new SwipeAdapter(context , null  , 0);
        videoList.setAdapter(swipeListAdapter);


        swipeContainer.setOnRefreshListener(this);

        getSupportLoaderManager().initLoader(LOADER_ID, null, this);

    }


    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        Log.d(TAG , "||onCreateLoader called||");
        return new CursorLoader(context ,MediaStore.Video.Media.EXTERNAL_CONTENT_URI ,null , null , null , MediaStore.Video.Media.TITLE + " collate nocase ");
    }


    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        if (swipeListAdapter != null && cursorLoader != null){

            Log.d(TAG , "||onLoadFinished called||");

            swipeListAdapter.swapCursor(cursor);

            swipeContainer.post(new Runnable() {
                @Override
                public void run() {
                    swipeContainer.setRefreshing(false);
                }
            });
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {
        if (swipeListAdapter != null) {
            Log.d(TAG , "||onLoaderReset called||");
            swipeListAdapter.swapCursor(null);
        }
    }


    /**
     * Whenever swipe refresh starts we get callback here.Here we can place our logic.
     */
    @Override
    public void onRefresh() {
        Log.d(TAG , "||onRefresh called||");
        getSupportLoaderManager().restartLoader(LOADER_ID , null ,this);
    }



    private class SwipeAdapter extends CursorAdapter{


        private VideoViewHolder videoViewHolder;

        public SwipeAdapter(Context context, Cursor c, int flags) {
            super(context, c, flags);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {

            videoViewHolder = new VideoViewHolder();
            View convertView = LayoutInflater.from(context).inflate(R.layout.row_swipe_refresh , parent , false);
            videoViewHolder.videoTitleTextView = (TextView) convertView.findViewById(R.id.titleTv);

            convertView.setTag(videoViewHolder);

            return convertView;
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {

            videoViewHolder = (VideoViewHolder) view.getTag();
            videoViewHolder.videoTitleTextView.setText(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE)));

        }
    }


    private class VideoViewHolder {
        private TextView videoTitleTextView;
    }
}


Result:(Displays the names of videos in phone using loader)