Showing posts with label Fragment. Show all posts
Showing posts with label Fragment. Show all posts

Friday, 12 December 2014

RecyclerView Tutorial


Android has introduced a new widget for displaying data collections which is a more advanced and flexible version of ListView. RecyclerView incorporates ListView and ViewHolder reusability concept very efficiently.

RecyclerView is very useful with large data collections whose content changes at runtime.

RecyclerView includes:

  1. Layout managers for positioning items. 
  2. Default animatios for common item operations , such as removal or addition of items.


Custom animation and layout managers can be defined as per the requirement.



Layout Manager:


RecyclerView provides 3 built-in layout managers:

  1. LinearLayoutManager shows items in a vertical or horizontal scrolling list. 
  2. GridLayoutManage shows items in a grid. 
  3. StaggeredGridLayoutManager shows items in a staggered grid. 

For custom layout manager, extend the RecyclerView.LayoutManager class.

Animation:



  1. Animations for adding and removing items are enabled by default.
  2. For custom animation, extend the RecyclerView.ItemAnimator class and use the RecyclerView.setItemAnimator() method.



RecyclerView Demo:

  1. Create a new Android project.
  2. Add the v7 support library, for eclipse follow the link and for gradle add: 
dependencies{
        compile com.android.support:recyclerview-v7:21.0.+
}
     3.  Add RecyclerView in xml:


<android.support.v7.widget.RecyclerView  
     android:id="@+id/recylcer_view"  
     android:layout_width="match_parent"  
     android:layout_height="match_parent"  
     android:scrollbars="vertical" />


   4. Create Adapter file MyRecyclerViewAdapter.java
      by extending RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>


public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>{

 private String[] mData;

 public MyRecyclerViewAdapter(String[] mData) {
  this.mData = mData;
 }

 @Override
 public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
  View v = LayoutInflater.from(viewGroup.getContext())
    .inflate(R.layout.list_item_layout, viewGroup, false);

  ViewHolder vh = new ViewHolder(v);
  return vh;

 }

 @Override
 public void onBindViewHolder(ViewHolder viewHolder, int i) {
  viewHolder.mTextView.setText(mData[i]);
 }

 @Override
 public int getItemCount() {
  if (mData != null)
   return mData.length;
  return 0;
 }

 public static class ViewHolder extends RecyclerView.ViewHolder {
  // each data item is just a string in this case
  public TextView mTextView;

  public ViewHolder(View itemView) {
   super(itemView);
   mTextView = (TextView)itemView.findViewById(R.id.txt);;
  }
 }
}


   5. Create Activity MyActivity.java

public class MyActivity extends Activity implements View.OnClickListener{

    private RecyclerView mRecyclerView;
    private MyRecyclerViewAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private GridLayoutManager mGridLayoutManager;
    private StaggeredGridLayoutManager mStaggeredGridLayoutManager;

    private String[] mSampleData = {"What is Android Lollipop?", "What is Android 5.0?",                     "What is RecyclerView?", "What is difference between RecyclerView and ListView?", "How does this demo app help?"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        mRecyclerView = (RecyclerView) findViewById(R.id.recylcer_view);
        mRecyclerView.setHasFixedSize(true);

        mAdapter = new MyRecyclerViewAdapter(mSampleData);
        mRecyclerView.setAdapter(mAdapter);
        applyLinearLayoutManager();
    }

    private void applyLinearLayoutManager(){
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
    }

    private void applyGridLayoutManager(){
        mGridLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);
        mRecyclerView.setLayoutManager(mGridLayoutManager);
    }


    private void applyStaggeredGridLayoutManager(){
        mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager);
    }




    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.my, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_linear)
            applyLinearLayoutManager();
        else if (id == R.id.action_grid)
            applyGridLayoutManager();
        else if (id == R.id.action_staggered)
            applyStaggeredGridLayoutManager();
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        int pos = mRecyclerView.getChildPosition(v);
        Toast.makeText(getApplicationContext(), mSampleData[pos], Toast.LENGTH_LONG).show();
    }
}



Friday, 10 February 2012

Fragments

Fragments are very useful in modularizing the code and UI. Fragment's use increases reusability in the project.

In this tutorial:

1.  How to use fragments with activity.
2.  Getting click events in the activity from fragments.
3.  Passing data from activity to fragments and fragments to fragments.
4.  Replacing fragments from activity and from fragment to fragment.

Note:
Here we will create one activity MainActivity and 3 fragments MainFragment, InputFragment, DetailFragment.
We will take some input from user in one fragments and will show the entered values in another fragments.

Let's start:

1.  Create a android project.
2.  Create a MainActivity.

MainActivity.java
public class MainActivity extends FragmentActivity implements ActivityListener{
    /** Called when the activity is first created.
     *  ActivityListener is the interface which is used
     *  to get callback from fragment.
     */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //Fragments are added programmatically here...
        MainFragment fragment = new MainFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.frameLayout, fragment);
        transaction.commit();

    }

    public void getData(Bundle bundle) {
        if ( bundle != null ) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            DetailFragment detailFragment = new DetailFragment();
            detailFragment.setArguments(bundle);
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.frameLayout, detailFragment);
            transaction.commit();
        }
    }

}

main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:id="@+id/frameLayout" >

</FrameLayout>

Note: To add fragments inside xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:id="@+id/frameLayout" >

<fragment 
  android:name="com.fragmentdemo.fragment.MainFragment"
  android:id="@+id/fragment"
  android:layout_weight="1"
  android:layout_width="0dp"
  android:layout_height="fill_parent" />

</FrameLayout>

3.  Create MainFragment.

MainFragment.java

public class MainFragment extends Fragment{

    private Button mInput;
   /**
     * Define Click listener for the button.
     */
    private OnClickListener inputClickListener = new OnClickListener() {
        public void onClick(View v) {
            FragmentManager fragmentManager = getFragmentManager();
            InputFragment inputFragment = new InputFragment();
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.frameLayout, inputFragment);
            transaction.addToBackStack(null);
            transaction.commit();
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.main_frag, null);
        contentView.setDrawingCacheEnabled(false);

        mInput = (Button)contentView.findViewById(R.id.btnInput);

        return contentView;
    }

    @Override
    public void onStart() {
        super.onStart();
        mInput.setOnClickListener(inputClickListener);
    }

}

main_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btnInput"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Add User Details"
        android:textSize="20dp" />

</LinearLayout>

4.  Create InputFragment.

InputFragment.java

public class InputFragment extends Fragment{

    private ActivityListener mListener;
    private Button mSubmit;
    private EditText mName, mOccupation, mDesignation;

    private OnClickListener submitClickListener = new OnClickListener() {
        public void onClick(View v) {
            if (mName.getText().toString().trim().length() == 0|| mOccupation.getText().toString().trim().length() == 0 || mDesignation.getText().toString().trim().length() == 0 ) {
            Toast.makeText( getActivity(), "Field can not be left empty.", Toast.LENGTH_SHORT).show();
            }
            else {
                Bundle bundle = new Bundle();
                bundle.putString("name", mName.getText().toString());
                bundle.putString("occupation", mOccupation.getText().toString());
                bundle.putString("designation", mDesignation.getText().toString());

        //Method1: Pass data to activity and then to fragment.
                if ( mListener != null )
                    mListener.getData(bundle);

        //Method2: pass data to fragment directly.
        FragmentManager fragmentManager = getFragmentManager();
        DetailFragment detailFragment = new DetailFragment();
        detailFragment.setArguments(bundle);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.frameLayout, detailFragment);
        transaction.remove(InputFragment.this);
        transaction.commit();
            }
        }
    };

    //Check for interface if activity has implemented it or not.
    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
        try {
            mListener = (ActivityListener)activity;
        }catch (ClassCastException e) {
            Toast.makeText( activity, "Activity must implement this interface.", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.input_frag, null);
        contentView.setDrawingCacheEnabled(false);

        mSubmit = (Button)contentView.findViewById(R.id.btnSubmit);
        mName = (EditText)contentView.findViewById(R.id.editName);
        mOccupation = (EditText)contentView.findViewById(R.id.editOccupation);
        mDesignation = (EditText)contentView.findViewById(R.id.editDesignation);

        Bundle bundle = getArguments();
        if ( bundle != null ) {
            mName.setText(bundle.getString("name"));
            mOccupation.setText(bundle.getString("occupation"));
            mDesignation.setText(bundle.getString("designation"));
        }
        return contentView;
    }

    @Override
    public void onStart() {
         super.onStart();
        mSubmit.setOnClickListener(submitClickListener);
    }

    //Define Interface for callback to activity.
    public interface ActivityListener {
        public void getData (Bundle bundle);
    }

}

input_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="20dp" >

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Name"
        android:textSize="20dp" />

    <EditText
        android:id="@+id/editName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Enter your name"
        android:textSize="20dp"
        android:padding="10dp"
        android:layout_marginTop="20dp" />

    <TextView
        android:id="@+id/occupation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Occupation"
        android:textSize="20dp"
        android:layout_marginTop="20dp" />

    <EditText
        android:id="@+id/editOccupation"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Enter your Occupation"
        android:textSize="20dp"
        android:padding="10dp"
        android:layout_marginTop="20dp" />

    <TextView
        android:id="@+id/designation"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Designation"
        android:textSize="20dp"
        android:layout_marginTop="20dp" />

    <EditText
        android:id="@+id/editDesignation"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Enter your Designation"
        android:textSize="20dp"
        android:padding="10dp"
        android:layout_marginTop="20dp" />

    <Button
        android:id="@+id/btnSubmit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Submit"
        android:textSize="20dp"
        android:layout_marginTop="20dp" />

</LinearLayout>

5.  Create DetailFragment.

DetailFragment.java

public class DetailFragment extends Fragment{

    private TextView mInfo;
    private Button mEditDetail, mClose;
    private Bundle mBundleData;

    private OnClickListener editClickListener = new OnClickListener() {
        public void onClick(View v) {
            InputFragment inputFragment = new InputFragment();
            inputFragment.setArguments(mBundleData);
            getFragmentManager().beginTransaction().
            replace(R.id.frameLayout, inputFragment).addToBackStack(null).commit();
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.detail_frag, null);
        contentView.setDrawingCacheEnabled(false);

        mInfo = (TextView)contentView.findViewById(R.id.detail);
        mEditDetail = (Button)contentView.findViewById(R.id.btnEdit);
        mBundleData = getArguments();
        if ( mBundleData != null ) {
            mInfo.setText("Name:  " + mBundleData.getString("name") + "\n"
                    + "Occupation:  " + mBundleData.getString("occupation") + "\n"
                    + "Designation:  " + mBundleData.getString("designation") + "\n" );
        }
        return contentView;
    }

    @Override
    public void onStart() {
        super.onStart();
        mEditDetail.setOnClickListener(editClickListener);
    }

}

detail_frag.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center" >

    <TextView
        android:id="@+id/detail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20dp" />

    <Button
        android:id="@+id/btnEdit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Edit User Details"
        android:textSize="20dp" />

</LinearLayout>

Source:

profile for Vineet Shukla at Stack Overflow, Q&A for professional and enthusiast programmers