Android App Bar Text Search for ListView – Example
In this tutorial we are going to show you how to implement custom ListView in Android with search bar to search and filter contents of list.
Sample Response:
1 |
[ { "s.no":0, "amt.pledged":15823, "blurb":"'Catalysts, Explorers & Secret Keepers: Women of Science Fiction' is a take-home exhibit & anthology by the Museum of Science Fiction.", "by":"Museum of Science Fiction", "country":"US", "currency":"usd", "end.time":"2016-11-01T23:59:00-04:00", "location":"Washington, DC", "percentage.funded":186, "num.backers":"219382", "state":"DC", "title":"Catalysts, Explorers & Secret Keepers: Women of SF", "type":"Town", "url":"/projects/1608905146/catalysts-explorers-and-secret-keepers-women-of-sf?ref=discovery" }, { "s.no":1, "amt.pledged":6859, "blurb":"A unique handmade picture book for kids & art lovers about a nervous monster who finds his courage with the help of a brave little girl", "by":"Tyrone Wells & Broken Eagle, LLC", "country":"US", "currency":"usd", "end.time":"2016-11-25T01:13:33-05:00", "location":"Portland, OR", "percentage.funded":8, "num.backers":"154926", "state":"OR", "title":"The Whatamagump (a hand-crafted story picture book)", "type":"Town", "url":"/projects/thewhatamagump/the-whatamagump-a-hand-crafted-story-picture-book?ref=discovery" }, { "s.no":2, "amt.pledged":17906, "blurb":"A horror comedy about a repairman who was in the wrong place at the wrong time thanks to mad scientists and monsters.", "by":"Tessa Stone", .....] |
APP Demo:
Creating New Project:
- Create a new project in your Anroid Studio and Go to File => New Project
- Fill in all the details and select Basic Activity template.
app_bar_main.xml – Modify and add Search box in action bar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="payu.android.sushil.com.payu_test.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <!-- To add Search Text box to action bar --> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay"> <EditText android:layout_width="200dp" android:layout_height="wrap_content" android:id="@+id/searchProjectTxt" android:layout_marginLeft="30dp" android:singleLine="true" android:hint="Search Here..." /> </android.support.v7.widget.Toolbar> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" /> </android.support.design.widget.CoordinatorLayout> |
content_main.xml – Using RecyclerView will create list or rows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="payu.android.sushil.com.payu_test.MainActivity" tools:showIn="@layout/app_bar_main"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="368dp" android:layout_height="wrap_content" android:clipToPadding="false" android:scrollbars="vertical" /> </android.support.constraint.ConstraintLayout> |
Next step is to design single item for our list. Create a new XML file under layout folder and name it as project_list_view.xml.
Right Click ⇒ New ⇒ Android XML File
In this tutorial I designed custom list using CardView to display all project details.
project_list_view.xml – Creates layout for individual items in the list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" android:elevation="3dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:id="@+id/card_view_layout" android:padding="5dp"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:textSize="10pt" android:textColor="@color/colorAccent" android:id="@+id/titleTxt" android:padding="5dp" android:text="Title" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="Pledged" android:padding="5dp" android:id="@+id/amountPledgedTxt" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="Backers" android:padding="5dp" android:id="@+id/backersTxt" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="No Of Days" android:padding="5dp" android:id="@+id/noOfDaysToGoTxt" /> </LinearLayout> </android.support.v7.widget.CardView> </RelativeLayout> |
Until now we have completed designing part of our app. Now we will write code to read JSON data
from REST api and parse it to display in our list row. Create a new java class file in your
src folder. Right Click on src ⇒ New ⇒ Class and name it as ProjectsDetailAdapter.java
ProjectsDetailAdapter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
public class ProjectsDetailAdapter extends RecyclerView.Adapter<ProjectsDetailAdapter.MyViewHolder> { private final Context context; private final List<ProjectsVo> projectList; public ProjectsDetailAdapter(Context context,List<ProjectsVo> projectList){ this.context = context; this.projectList = projectList; } @Override public long getItemId(int position) { return position; } @Override public int getItemCount() { return projectList.size(); } @Override public void onBindViewHolder(final MyViewHolder holder, int position) { final ProjectsVo project = projectList.get(position); holder.titleTxt.setText(project.getTitle()); holder.amountPledgedTxt.setText("Pleadged - "+project.getAmountPledged()); holder.backersTxt.setText("Backers - "+project.getNumBackers()); if(project.getEndTime() != null && project.getEndTime().length()!=0) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD'T'hh:mm:ss"); //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); Date rem = null; try { Date date = sdf.parse(project.getEndTime()); holder.noOfDaysToGoTxt.setText("Time - "+sdf.format(date)); } catch (ParseException e) { e.printStackTrace(); } } holder.cardViewLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(v.getContext().getApplicationContext(), DetailActivity.class); intent.putExtra("title", project.getTitle()); intent.putExtra("amount", project.getAmountPledged()); intent.putExtra("backers", project.getNumBackers()); v.getContext().startActivity(intent); } }); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.project_list_view, parent, false); return new MyViewHolder(itemView); } public class MyViewHolder extends RecyclerView.ViewHolder { public TextView titleTxt, amountPledgedTxt, backersTxt, noOfDaysToGoTxt; public LinearLayout cardViewLayout; public MyViewHolder(View view) { super(view); titleTxt = (TextView) view.findViewById(R.id.titleTxt); amountPledgedTxt = (TextView) view.findViewById(R.id.amountPledgedTxt); backersTxt = (TextView) view.findViewById(R.id.backersTxt); noOfDaysToGoTxt = (TextView) view.findViewById(R.id.noOfDaysToGoTxt); cardViewLayout = (LinearLayout)view.findViewById(R.id.card_view_layout); } } } |
Now we will create POJO class to map data from REST response to java class. Create a new java class file in your
src folder. Right Click on src ⇒ New ⇒ Class and name it as ProjectsVo.java
ProjectsVo.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class ProjectsVo { @SerializedName("s.no") private String sNo; @SerializedName("amt.pledged") private String amountPledged; private String blurb; private String by; private String country; private String currency; @SerializedName("end.time") private String endTime; private String location; @SerializedName("percentage.funded") private String percntFunded; @SerializedName("num.backers") private String numBackers; private String state; private String title; private String type; private String url; } |
Now open your MainActivity class and add below code. In the below code I am getting json response from url and parsing it.
We are using GetKickStartProjects class to read data from REST api on AsynchTask. AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private static String KIKSTARTER_URL = "http://starlord.hackerearth.com/kickstarter"; private RecyclerView recyclerView; ProjectsDetailAdapter adapter; List<ProjectsVo> projectList; List<ProjectsVo> projectListCache = new ArrayList<>(); EditText searchTxt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); searchTxt = (EditText)findViewById(R.id.searchProjectTxt); projectList = new ArrayList<>(); new GetKickStartProjects().execute(); recyclerView = (RecyclerView)findViewById(R.id.recycler_view); adapter = new ProjectsDetailAdapter(this, projectList); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(adapter); searchTxt.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changed the Text filter(cs.toString()); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { } @Override public void afterTextChanged(Editable arg0) { } }); } ............ } |
Add Permissions in AndroidManifest.xml
Open your AndroidManifest.xml file add INTERNET permission.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="payu.android.sushil.com.payu_test"> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".DetailActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" /> </activity> </application> </manifest> |
Final Output:
Finally you should see below output
Download sample code here