ํ์ฌ ์ฑ์ ๋จธํฐ๋ฆฌ์ผ ๋์์ธ์ผ๋ก ๋ณํํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๋ ์ค์ ๋๋ค. ์ง๊ธ ์กฐ๊ธ ๋ฉ์ท์ต๋๋ค. ํด๋ฐ๊ฐ ์ถ๊ฐ๋์๊ณ ๋ด ํ์ ์๋์ด ๋ชจ๋ ์ฝํ ์ธ ๋ฅผ ์ค๋ฒ๋ ์ดํ๋๋ก ๋ง๋ค์์ต๋๋ค.
์ด์ ์ฌ๋ฃ ๊ฐ์ด๋ ๋ผ์ธ ๊ณผ ๋น์ทํ ํ์ฅ ๊ฐ๋ฅํ ๊ฒ์์ ์์ฑํ๋ ค๊ณ ํฉ๋๋ค .

์ด๊ฒ์ด ๋ฐ๋ก ์ง๊ธ ์ป์ ๊ฒ์ด๋ฉฐ ์์ ๊ฐ์ด ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๋ด ๋ฉ๋ด XML์ ๋๋ค.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:icon="@android:drawable/ic_menu_search"
android:title="Search"
app:showAsAction="always"
app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
์๋ํ์ง๋ง SearchView๋ก ํ์ฅ๋๋ ๋ฉ๋ด ํญ๋ชฉ์ด ํ์๋๋ฉฐ ๋ด ๋ชฉ๋ก์ ์ ํํฐ๋ง ํ ์ ์์ต๋๋ค. ๊ทธ๋๋ ์ฒซ ๋ฒ์งธ ๊ทธ๋ฆผ์ฒ๋ผ ๋ณด์ด์ง ์์ต๋๋ค.
๋ด๊ฐ ์ฌ์ฉํ๋ ค๊ณ MenuItemCompat.setOnActionExpandListener()์ R.id.action_search๋๋ ๋ค๋ก ํ์ดํ์ ํ ์์ด์ฝ์ ๋ณ๊ฒฝํ ์ ์๋๋ก,ํ์ง๋ง ์๋ํ์ง ์์ต๋๋ค. ๋ฆฌ์ค๋์์ ์๋ฌด๊ฒ๋ ๋ฐ์ํ์ง ์์ต๋๋ค. ๊ทธ๊ฒ์ด ํจ๊ณผ๊ฐ ์์์ง๋ง ์ฌ์ ํ ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง์ ๊ทธ๋ฆฌ ๊ฐ๊น์ง๋ ์์ต๋๋ค.
์ฌ๋ฃ ๊ฐ์ด๋ ๋ผ์ธ์ฒ๋ผ ๋ณด์ด๋ ์๋ก์ด appcompat ๋๊ตฌ ๋ชจ์์์ SearchView๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ
๋ต๋ณ
android.support.v7๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ค์ ๋ก์ด ์์
์ ์ํํ๋ ๊ฒ์ด ๋งค์ฐ ์ฝ์ต๋๋ค .
1 ๋จ๊ณ
๋ฉ๋ด ํญ๋ชฉ ์ ์ธ
<item android:id="@+id/action_search"
android:title="Search"
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
2 ๋จ๊ณ
SearchView๋ฅผ ํ์ฅ AppCompatActivityํ๊ณ onCreateOptionsMenu์ค์ ํ์ญ์์ค.
import android.support.v7.widget.SearchView;
...
public class YourActivity extends AppCompatActivity {
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_home, menu);
// Retrieve the SearchView and plug it into SearchManager
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return true;
}
...
}
๊ฒฐ๊ณผ
๋ต๋ณ
์ผ์ฃผ์ผ ๋์ ์์๊ป๋ผ๋ฅผ ํผ ํ. ๋ด๊ฐ ์์ ๋ธ ๊ฒ ๊ฐ์
ํด๋ฐ ๋ด์์ EditText ๋ง ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์ด๊ฒ์ reddit์์ oj88์ ์ํด ์ ์๋์์ต๋๋ค.
๋๋ ์ด์ ์ด๊ฒ์ ๊ฐ์ง๊ณ ์๋ค :
๋จผ์ ๋ด ํ๋์ onCreate () ๋ด๋ถ์ ์ค๋ฅธ์ชฝ๊ณผ ๊ฐ์ด ์ด๋ฏธ์ง๋ณด๊ธฐ๊ฐ์๋ EditText๋ฅผ ํด๋ฐ์ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐํ๋ค :
// Setup search container view
searchContainer = new LinearLayout(this);
Toolbar.LayoutParams containerParams = new Toolbar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
containerParams.gravity = Gravity.CENTER_VERTICAL;
searchContainer.setLayoutParams(containerParams);
// Setup search view
toolbarSearchView = new EditText(this);
// Set width / height / gravity
int[] textSizeAttr = new int[]{android.R.attr.actionBarSize};
int indexOfAttrTextSize = 0;
TypedArray a = obtainStyledAttributes(new TypedValue().data, textSizeAttr);
int actionBarHeight = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
a.recycle();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, actionBarHeight);
params.gravity = Gravity.CENTER_VERTICAL;
params.weight = 1;
toolbarSearchView.setLayoutParams(params);
// Setup display
toolbarSearchView.setBackgroundColor(Color.TRANSPARENT);
toolbarSearchView.setPadding(2, 0, 0, 0);
toolbarSearchView.setTextColor(Color.WHITE);
toolbarSearchView.setGravity(Gravity.CENTER_VERTICAL);
toolbarSearchView.setSingleLine(true);
toolbarSearchView.setImeActionLabel("Search", EditorInfo.IME_ACTION_UNSPECIFIED);
toolbarSearchView.setHint("Search");
toolbarSearchView.setHintTextColor(Color.parseColor("#b3ffffff"));
try {
// Set cursor colour to white
// https://stackoverflow.com/a/26544231/1692770
// https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(toolbarSearchView, R.drawable.edittext_whitecursor);
} catch (Exception ignored) {
}
// Search text changed listener
toolbarSearchView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Fragment mainFragment = getFragmentManager().findFragmentById(R.id.container);
if (mainFragment != null && mainFragment instanceof MainListFragment) {
((MainListFragment) mainFragment).search(s.toString());
}
}
@Override
public void afterTextChanged(Editable s) {
// https://stackoverflow.com/a/6438918/1692770
if (s.toString().length() <= 0) {
toolbarSearchView.setHintTextColor(Color.parseColor("#b3ffffff"));
}
}
});
((LinearLayout) searchContainer).addView(toolbarSearchView);
// Setup the clear button
searchClearButton = new ImageView(this);
Resources r = getResources();
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, r.getDisplayMetrics());
LinearLayout.LayoutParams clearParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
clearParams.gravity = Gravity.CENTER;
searchClearButton.setLayoutParams(clearParams);
searchClearButton.setImageResource(R.drawable.ic_close_white_24dp); // TODO: Get this image from here: https://github.com/google/material-design-icons
searchClearButton.setPadding(px, 0, px, 0);
searchClearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toolbarSearchView.setText("");
}
});
((LinearLayout) searchContainer).addView(searchClearButton);
// Add search view to toolbar and hide it
searchContainer.setVisibility(View.GONE);
toolbar.addView(searchContainer);
์ด๊ฒ์ ํจ๊ณผ๊ฐ ์์์ง๋ง ํ ๋ฒํผ์ ๋๋ ์ ๋ onOptionsItemSelected ()๊ฐ ํธ์ถ๋์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๊ทธ๋์ ํ ๋ฒํผ์ ๋๋ฌ ๊ฒ์์ ์ทจ์ ํ ์ ์์์ต๋๋ค. ํ ๋ฒํผ์ ํด๋ฆญ ๋ฆฌ์ค๋๋ฅผ ๋ฑ๋กํ๋ ๋ช ๊ฐ์ง ๋ฐฉ๋ฒ์ ์๋ํ์ง๋ง ์๋ํ์ง ์์์ต๋๋ค.
๊ฒฐ๊ตญ ๋๋ ๊ฐ์ง๊ณ ์๋ ActionBarDrawerToggle์ด ๋ฌผ๊ฑด์ ๋ฐฉํดํ๊ณ ์๋ค๋ ๊ฒ์ ์์์ผ๋ฏ๋ก ๊ทธ๊ฒ์ ์ ๊ฑฐํ์ต๋๋ค. ์ด ๋ฆฌ์ค๋๋ ๋ค์ ์์ ์ ์์ํ์ต๋๋ค.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// toolbarHomeButtonAnimating is a boolean that is initialized as false. It's used to stop the user pressing the home button while it is animating and breaking things.
if (!toolbarHomeButtonAnimating) {
// Here you'll want to check if you have a search query set, if you don't then hide the search box.
// My main fragment handles this stuff, so I call its methods.
FragmentManager fragmentManager = getFragmentManager();
final Fragment fragment = fragmentManager.findFragmentById(R.id.container);
if (fragment != null && fragment instanceof MainListFragment) {
if (((MainListFragment) fragment).hasSearchQuery() || searchContainer.getVisibility() == View.VISIBLE) {
displaySearchView(false);
return;
}
}
}
if (mDrawerLayout.isDrawerOpen(findViewById(R.id.navigation_drawer)))
mDrawerLayout.closeDrawer(findViewById(R.id.navigation_drawer));
else
mDrawerLayout.openDrawer(findViewById(R.id.navigation_drawer));
}
});
์ด์ ํ ๋ฒํผ์ผ๋ก ๊ฒ์์ ์ทจ์ ํ ์ ์์ง๋ง ๋ค๋ก ๋ฒํผ์ ๋๋ฌ ์ทจ์ ํ ์๋ ์์ต๋๋ค. ๊ทธ๋์ ์ด๊ฒ์ onBackPressed ()์ ์ถ๊ฐํ์ต๋๋ค.
FragmentManager fragmentManager = getFragmentManager();
final Fragment mainFragment = fragmentManager.findFragmentById(R.id.container);
if (mainFragment != null && mainFragment instanceof MainListFragment) {
if (((MainListFragment) mainFragment).hasSearchQuery() || searchContainer.getVisibility() == View.VISIBLE) {
displaySearchView(false);
return;
}
}
์ด ๋ฉ์๋๋ฅผ ์์ฑํ์ฌ EditText ๋ฐ ๋ฉ๋ด ํญ๋ชฉ์ ๊ฐ์์ฑ์ ํ ๊ธํฉ๋๋ค.
public void displaySearchView(boolean visible) {
if (visible) {
// Stops user from being able to open drawer while searching
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
// Hide search button, display EditText
menu.findItem(R.id.action_search).setVisible(false);
searchContainer.setVisibility(View.VISIBLE);
// Animate the home icon to the back arrow
toggleActionBarIcon(ActionDrawableState.ARROW, mDrawerToggle, true);
// Shift focus to the search EditText
toolbarSearchView.requestFocus();
// Pop up the soft keyboard
new Handler().postDelayed(new Runnable() {
public void run() {
toolbarSearchView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
toolbarSearchView.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
}
}, 200);
} else {
// Allows user to open drawer again
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
// Hide the EditText and put the search button back on the Toolbar.
// This sometimes fails when it isn't postDelayed(), don't know why.
toolbarSearchView.postDelayed(new Runnable() {
@Override
public void run() {
toolbarSearchView.setText("");
searchContainer.setVisibility(View.GONE);
menu.findItem(R.id.action_search).setVisible(true);
}
}, 200);
// Turn the home button back into a drawer icon
toggleActionBarIcon(ActionDrawableState.BURGER, mDrawerToggle, true);
// Hide the keyboard because the search box has been hidden
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(toolbarSearchView.getWindowToken(), 0);
}
}
ํด๋ฐ์ ํ ๋ฒํผ์ ์๋ ์์ด์ฝ๊ณผ ๋ค๋ก ๋ฒํผ ์ฌ์ด์์ ์ ํํ๋ ๋ฐฉ๋ฒ์ด ํ์ํ์ต๋๋ค. ๊ฒฐ๊ตญ ์ด SO ๋ต๋ณ ์์ ์๋ ๋ฐฉ๋ฒ์ ์ฐพ์์ต๋๋ค . ์ข ๋ ์ดํดํ๊ธฐ ์ฝ๊ฒ ์ฝ๊ฐ ์์ ํ์ง๋ง :
private enum ActionDrawableState {
BURGER, ARROW
}
/**
* Modified version of this, https://stackoverflow.com/a/26836272/1692770<br>
* I flipped the start offset around for the animations because it seemed like it was the wrong way around to me.<br>
* I also added a listener to the animation so I can find out when the home button has finished rotating.
*/
private void toggleActionBarIcon(final ActionDrawableState state, final ActionBarDrawerToggle toggle, boolean animate) {
if (animate) {
float start = state == ActionDrawableState.BURGER ? 1.0f : 0f;
float end = Math.abs(start - 1);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ValueAnimator offsetAnimator = ValueAnimator.ofFloat(start, end);
offsetAnimator.setDuration(300);
offsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float offset = (Float) animation.getAnimatedValue();
toggle.onDrawerSlide(null, offset);
}
});
offsetAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
toolbarHomeButtonAnimating = false;
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
toolbarHomeButtonAnimating = true;
offsetAnimator.start();
}
} else {
if (state == ActionDrawableState.BURGER) {
toggle.onDrawerClosed(null);
} else {
toggle.onDrawerOpened(null);
}
}
}
์ด๊ฒ์ ํจ๊ณผ๊ฐ ์์ต๋๋ค. ๋๋ ๊ธธ์ ๋ฐ๋ผ ์ฐพ์ ๋ช ๊ฐ์ง ๋ฒ๊ทธ๋ฅผ ํด๊ฒฐํ์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด 100 %๋ผ๊ณ ์๊ฐํ์ง ์์ง๋ง ๊ทธ๊ฒ์ ๋๋ฅผ ์ํด ์ถฉ๋ถํ ์ ์๋ํฉ๋๋ค.
ํธ์ง : Java ๋์ XML๋ก ๊ฒ์๋ณด๊ธฐ๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด ๋ค์์ ์ํํ์ญ์์ค.
toolbar.xml :
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
contentInsetLeft="72dp"
contentInsetStart="72dp"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
app:contentInsetLeft="72dp"
app:contentInsetStart="72dp"
app:popupTheme="@style/ActionBarPopupThemeOverlay"
app:theme="@style/ActionBarThemeOverlay">
<LinearLayout
android:id="@+id/search_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<EditText
android:id="@+id/search_view"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="@android:color/transparent"
android:gravity="center_vertical"
android:hint="Search"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingLeft="2dp"
android:singleLine="true"
android:textColor="#ffffff"
android:textColorHint="#b3ffffff" />
<ImageView
android:id="@+id/search_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:src="@drawable/ic_close_white_24dp" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
ํ๋์ onCreate () :
searchContainer = findViewById(R.id.search_container);
toolbarSearchView = (EditText) findViewById(R.id.search_view);
searchClearButton = (ImageView) findViewById(R.id.search_clear);
// Setup search container view
try {
// Set cursor colour to white
// https://stackoverflow.com/a/26544231/1692770
// https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(toolbarSearchView, R.drawable.edittext_whitecursor);
} catch (Exception ignored) {
}
// Search text changed listener
toolbarSearchView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Fragment mainFragment = getFragmentManager().findFragmentById(R.id.container);
if (mainFragment != null && mainFragment instanceof MainListFragment) {
((MainListFragment) mainFragment).search(s.toString());
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
// Clear search text when clear button is tapped
searchClearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toolbarSearchView.setText("");
}
});
// Hide the search view
searchContainer.setVisibility(View.GONE);
๋ต๋ณ
๋๋ ์ค๋๋ ์ค๋ ๋๋ฅผ ์๊ณ ์์ง๋ง ์ฌ์ ํ ๋ฐฉ๊ธ ๋ง๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฒ์ํฉ๋๋ค. ์ด๊ฒ์ด ๋๊ตฐ๊ฐ๋ฅผ ๋์ธ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๋ต๋ณ
์ง๋ฌธ์ ์ฒซ ๋ฒ์งธ ์คํฌ๋ฆฐ ์ท์ ๊ณต๊ฐ ์์ ฏ์ด ์๋๋๋ค. ์ง์ SearchView ( android.support.v7.widget.SearchView)๋ Android 5.0 Lollipop์ SearchView ( android.widget.SearchView)์ ์ ์ฌ ํฉ๋๋ค. ๋ ๋ฒ์งธ ์คํฌ๋ฆฐ ์ท์ Google Play์ ๊ฐ์ ๋ค๋ฅธ ์ฌ๋ฃ๋ก ์ค๊ณ๋ ์ฑ์์ ์ฌ์ฉ๋ฉ๋๋ค.
์ฒซ ๋ฒ์งธ ์คํฌ๋ฆฐ ์ท์ SearchView๋ ๋๋ผ์ด๋ธ, YouTube ๋ฐ ๊ธฐํ ๋น๊ณต๊ฐ ์์ค Google Apps์์ ์ฌ์ฉ๋ฉ๋๋ค. ๋คํํ๋ Android 5.0 Dialer ์์๋ ์ฌ์ฉ๋ฉ๋๋ค . ๋ทฐ๋ฅผ ๋ฐฑ ํฌํธํ๋ ค๊ณ ํ ์ ์์ง๋ง ์ผ๋ถ 5.0 API๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ณด๊ณ ์ถ์ ์์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
SearchEditTextLayout , AnimUtils ๋ฐ DialtactsActivity ๋ฅผ ์ฌ์ฉํ์ฌ View ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์ดํดํ์ญ์์ค. ContactsCommon์ ๋ฆฌ์์ค๋ ํ์ํฉ๋๋ค .
ํ์ด์ ๋น๋๋ค.
๋ต๋ณ
์ด ์์ ์ ์ํํ๋ ค๋ ์๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1 ๋จ๊ณ : ์ด๋ฆ์ด ์ง์ ๋ ์คํ์ผ ๋ง๋ค๊ธฐ SearchViewStyle
<style name="SearchViewStyle" parent="Widget.AppCompat.SearchView">
<!-- Gets rid of the search icon -->
<item name="searchIcon">@drawable/search</item>
<!-- Gets rid of the "underline" in the text -->
<item name="queryBackground">@null</item>
<!-- Gets rid of the search icon when the SearchView is expanded -->
<item name="searchHintIcon">@null</item>
<!-- The hint text that appears when the user has not typed anything -->
<item name="queryHint">@string/search_hint</item>
</style>
2 ๋จ๊ณ : ์ด๋ฆ์ด ์ง์ ๋ ๋ ์ด์์ ์์ฑ simple_search_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.SearchView
android:layout_gravity="end"
android:layout_height="wrap_content"
android:layout_width="match_parent"
style="@style/SearchViewStyle"
xmlns:android="http://schemas.android.com/apk/res/android" />
3 ๋จ๊ณ :์ด ๊ฒ์๋ณด๊ธฐ์ ๋ํ ๋ฉ๋ด ํญ๋ชฉ ์์ฑ
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
app:actionLayout="@layout/simple_search_view_item"
android:title="@string/search"
android:icon="@drawable/search"
app:showAsAction="always" />
</menu>
4 ๋จ๊ณ : ๋ฉ๋ด ํฝ์ฐฝ
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_searchable_activity, menu);
return true;
}
๊ฒฐ๊ณผ:
๋ด๊ฐ ํ ์ ์์๋ ์ ์ผํ ๊ฒ์์ ์ ์ฒด ๋๋น๋ฅผ ์ฑ์ฐ๋ ๊ฒ Toolbar์
๋๋ค. ๋๊ตฐ๊ฐ ๋ด๊ฐ ๊ทธ๋ ๊ฒ ํ ์ ์๋ค๋ฉด ๊ทธ๊ฒ์ ํฉ๊ธ์ ์ผ ๊ฒ์
๋๋ค.
๋ต๋ณ
์ํ๋ SearchView ๋ชจ์์ ์ป๊ธฐ ์ํด ์คํ์ผ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋จผ์ styleSearchView ๋ฅผ ์์ฑ ํด์ผํฉ๋๋ค.
<style name="CustomSearchView" parent="Widget.AppCompat.SearchView">
<item name="searchIcon">@null</item>
<item name="queryBackground">@null</item>
</style>
์ด ๊ธฐ์ฌ์ โSearchViewโ์น์ ์์ ์ฐพ์ ์์๋ ์ ์ฒด ์์ฑ ๋ชฉ๋ก์ ๋๋ค .
๋์งธ, ๋น์ ์์ ๋ง๋ค ํ์๊ฐ style๋น์ ์ ์ํด Toolbar, ์ก์
๋ฐ๋ก ์ฌ์ฉ๋๋ค :
<style name="ToolbarSearchView" parent="Base.ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="searchViewStyle">@style/CustomSearchView</item>
</style>
๋ง์ง๋ง์ผ๋ก ํด๋ฐ ํ ๋ง ์์ฑ์ ๋ค์๊ณผ ๊ฐ์ด ์ ๋ฐ์ดํธํด์ผํฉ๋๋ค.
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolbarSearchView" />
๊ฒฐ๊ณผ:
์ฐธ๊ณ : Toolbarํ
๋ง ์์ฑ์ ์ง์ ๋ณ๊ฒฝํด์ผํฉ๋๋ค . ๊ธฐ๋ณธ ํ
๋ง searchViewStyle์์ฑ ๋ง ์
๋ฐ์ดํธํ๋ฉด์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค Toolbar.
๋ต๋ณ
์ํ๋ ํจ๊ณผ๋ฅผ ์ป์ ์์๋ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์์ด ์ฌ๋ฃ ๊ฒ์ ๋ทฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ์ ๋๋ค. ๊ฒ์ ๊ธฐ๋ก์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ฉฐ๋ณด๊ธฐ์ ๊ฒ์ ์ ์์ ์ ๊ณต ํ ์๋ ์์ต๋๋ค.
์ํ : (ํฌ๋ฅดํฌ๊ฐ์ด๋ก ํ์๋์ง๋ง ์์ด์ ์ดํ๋ฆฌ์์ด๋ก๋ ์๋ํฉ๋๋ค).
์ค์
์ด lib๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ์ฑ ๋ชจ๋ MsvAuthority์ br.com.maukerํจํค์ง ๋ด์ ์ด๋ฆ์ด ์ง์ ๋ ํด๋์ค๋ฅผ ๊ตฌํ ํด์ผํ๋ฉฐ๋ผ๋ ๊ณต์ฉ ์ ์ ๋ฌธ์์ด ๋ณ์๊ฐ ์์ด์ผํฉ๋๋ค CONTENT_AUTHORITY. ์ํ๋ ๊ฐ์ ์ง์ ํ๊ณ ๋งค๋ํ์คํธ ํ์ผ์ ๋์ผํ ์ด๋ฆ์ ์ถ๊ฐํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค . lib๋์ด ํ์ผ์ ์ฌ์ฉํ์ฌ ์ปจํ
์ธ ์ ๊ณต์ ๊ถํ์ ์ค์ ํฉ๋๋ค.
์:
MsvAuthority.java
package br.com.mauker;
public class MsvAuthority {
public static final String CONTENT_AUTHORITY = "br.com.mauker.materialsearchview.searchhistorydatabase";
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<application ... >
<provider
android:name="br.com.mauker.materialsearchview.db.HistoryProvider"
android:authorities="br.com.mauker.materialsearchview.searchhistorydatabase"
android:exported="false"
android:protectionLevel="signature"
android:syncable="true"/>
</application>
</manifest>
์ฉ๋ฒ
์ฌ์ฉํ๋ ค๋ฉด ์ข ์์ฑ์ ์ถ๊ฐํ์ญ์์ค.
compile 'br.com.mauker.materialsearchview:materialsearchview:1.2.0'
๊ทธ๋ฐ ๋ค์ Activity๋ ์ด์์ ํ์ผ์์ ๋ค์์ ์ถ๊ฐํ์ญ์์ค.
<br.com.mauker.materialsearchview.MaterialSearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
๊ทธ ํ, ๋น์ ์ ๋จ์ง ์ป์ํด์ผํฉ๋๋ค MaterialSearchView์ฌ์ฉํ์ฌ ์ฐธ์กฐ๋ฅผ getViewById()ํ๊ณ , ๊ทธ๊ฒ์ ์ด๊ฑฐ ๋ ์ฌ์ฉํ์ฌ ์ข
๋ฃ MaterialSearchView#openSearch()ํ๊ณ MaterialSearchView#closeSearch().
์ถ์ : ์์๋ฟ๋ง ์๋๋ผ๋ณด๊ธฐ๋ฅผ ์ด๊ณ ๋ซ์ ์ ์์ต๋๋ค Toolbar. ํ๋กํ
์ก์
๋ฒํผ๊ณผ ๊ฐ์ openSearch()๊ธฐ๋ณธ์ ์ผ๋ก ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค Button.
// Inside onCreate()
MaterialSearchView searchView = (MaterialSearchView) findViewById(R.id.search_view);
Button bt = (Button) findViewById(R.id.button);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
searchView.openSearch();
}
});
๋ค๋ก ๋ฒํผ์ ์ฌ์ฉํ์ฌ ๋ค์์ ์ํํ์ฌ๋ณด๊ธฐ๋ฅผ ๋ซ์ ์๋ ์์ต๋๋ค.
@Override
public void onBackPressed() {
if (searchView.isOpen()) {
// Close the search on the back button press.
searchView.closeSearch();
} else {
super.onBackPressed();
}
}
lib ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ๋ด์ฉ ์ github ํ์ด์ง๋ฅผ ํ์ธํ์ญ์์ค .