1

I'm working to implement a SearchView on my Fragment's RecyclerView as shown here. When the user taps the search button I want the Menu Item for the SearchView to Override the toolbar and display the area for them to search. If I don't use my custom style for the toolbar it works fine but when I do it get the images below.

Here is what I am currently getting: Toolbar with SearchView menu item

Toolbar with SearchView compressing but not overlapping the Toolbar title

Example of SearchView menu working properly

This is the class that the EventListActivity inherits from:

public abstract class SingleFragmentActivity extends AppCompatActivity {

    protected abstract Fragment createFragment();

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

        // Manages our fragments. We can call it to add a fragment to an activity in code
        FragmentManager fm = getSupportFragmentManager();
        // Check if fragment of R.id already exits
        // The FragmentManager saves out the list of fragments on rotation destruction or memory reclaim
        Fragment fragment = fm.findFragmentById(R.id.fragment_container);
        // If the the fragment does not exist, create it
        if(fragment == null) {
            fragment = createFragment();
            // Create a new fragment transaction, include one add operation in it, and then commit it
            fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
        }
    }

}

This creates the fragment that manages and works with the RecyclerView:

public class EventListActivity extends SingleFragmentActivity {

@Override
protected Fragment createFragment() {

    // Setting arguments for the new fragment created from the intent from EventFeedResultWrapper
    EventListFragment fragment = new EventListFragment();
    fragment.setArguments(getIntent().getExtras());
    return fragment;
}
}

Fragment that holds the RecyclerViewthat the SearchView will interface with. This is where the search menu button is inflated. It is where I've been trying to modify the toolbar:

public class EventListFragment extends Fragment {

private RecyclerView mEventRecyclerView;
private EventAdapter mAdapter;


// Telling the FragmentManager that it is
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

        ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
        ((AppCompatActivity)getActivity()).getSupportActionBar().setCustomView(R.layout.action_bar_center);
        View sabView = ((AppCompatActivity)getActivity()).getSupportActionBar().getCustomView();
        TextView titleTxtView = (TextView) sabView.findViewById(R.id.action_bar_title);
        titleTxtView.setText("Events Calendar");
        ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowCustomEnabled(true);

    setHasOptionsMenu(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.eventcalendar_fragment_event_list, container, false);

     mEventRecyclerView = (RecyclerView) view.findViewById(R.id.event_recycler_view);
     // RecyclerView requires a layout manager to work, layout manager is in charge of position items on screen
     mEventRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    updateUI();

    return view;
}

// Populate the menu instance
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.eventcalendar_menu, menu);
}

// When we edit a EventActivity this saves it back to the EventListActivity
// onResume over onStart because we cannot assume the activity will be stopped
// when another activity is in front of it. If the other activity is transparent
// then the activity might just get paused. If it is paused then onStart() will not be called
// but on resume will be called.
// NOTE: In general onResume() is the safest place to take action to update a fragment's view
@Override
public void onResume() {
    super.onResume();
    updateUI();
}

private void updateUI() {
    // Read in the events saved in to EventFeedResultWrapper by the Async task in ParseEventFeedTask
    EventFeedResultWrapper wrapper = (EventFeedResultWrapper) getArguments().getSerializable(ParseEventFeedTask.EXTRA_RESULTS_LIST);
    // Make sure wrapper is not null, it will NEVER be null
    if(wrapper == null){
        throw new RuntimeException("Error: The wrapper is null!");
    }

    // Get all the events from the wrapper/serializable
    List<Event> events = wrapper.getEventFeedResults();
    // Gets the context that we don't use rofl
    EventCal eventCal = EventCal.get(getActivity());
    // Add all the events we got from the wrapper to our event manager eventCal
    eventCal.addEvents(events);

    // Check to see if the EventAdapter is already setup
    if(mAdapter == null) {
        mAdapter = new EventAdapter(events);
        mEventRecyclerView.setAdapter(mAdapter);
    } else {
        mAdapter.notifyDataSetChanged();
    }


}

//Adapter here - removed code since it doesn't do anything with the toolbar
//RecycleView onClickLister - removed code since it doesn't do anything with the toolbar

}

This is the custom XML Style

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical" >
    <TextView
        android:id="@+id/action_bar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="#ffffff"
        android:textSize="24dp"/>
</LinearLayout>

Event Menu 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:title="Search"
          app:actionViewClass="android.support.v7.widget.SearchView"
          app:showAsAction="always"/>

</menu>
Angel
  • 311
  • 1
  • 4
  • 16

1 Answers1

0

Did you missed android:orientation="vertical". The text is displaying vertically. You want horizontal right?

Oh nvm i didn't understood it at first. The problem must be the inflating of the custom view, for some reason it seems it keeps the original view there and inflated it somewhere else. Give me 1s i'll update the answer when i find the issue

Check here: getSupportActionBar().setCustomView(view) does not fill entire actionbar

Similar problem. First and Second answer

EDIT2: Remove the code from EventListFragment onCreate. You don't need to inflate a searchView, you can use the default one.

@Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_main, menu);
        super.onCreateOptionsMenu(menu, inflater);
        setOptionsMenu(menu);
    }

public void setOptionsMenu(Menu menu) {                
        MenuItem search = menu.findItem(R.id.search);

        SearchView searchView;
        /**
         * Setup the SearchView
         */
        SearchManager searchManager = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);

        final boolean[] modifiedOriginal = {false};

        searchView = (SearchView) search.getActionView();

        if (searchView != null) {
            searchView.setSearchableInfo(searchManager.getSearchableInfo(((Activity) context).getComponentName()));

            MenuItemCompat.setOnActionExpandListener(search, new MenuItemCompat.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    ...
                    return true;
                }

                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    ...
                    return true;
                }
            });

            final EditText et = ButterKnife.findById(searchView, android.support.v7.appcompat.R.id.search_src_text);

            et.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                }

                @Override
                public void afterTextChanged(Editable editable) {
                    String s = editable.toString();
                    if (!s.equals("") && !s.equals(" ")) {
                       ...
                    }
                }
            });

            ButterKnife.findById(searchView, android.support.v7.appcompat.R.id.search_close_btn).setOnClickListener(
                    view -> {
                        ...
                        et.setText("");
                    }
            );

        }
    }

You can leave your menu xml as it is.

Community
  • 1
  • 1
johnny_crq
  • 4,291
  • 5
  • 39
  • 64
  • The orientation="vertical" lets me center the title text in the ActionBar. Setting it to "horizontal" doesn't fix the issue, rather it just left aligns the title to the left. EDIT: I saw your edit thanks. – Angel Mar 29 '16 at 21:26
  • any reason you do not use the default searchview? – johnny_crq Mar 29 '16 at 21:30
  • Default SearchView? As in, without the Support Library? – Angel Mar 29 '16 at 21:35
  • try this: getSupportActionBar().setDisplayShowCustomEnabled(true) after you set the custo view – johnny_crq Mar 29 '16 at 21:39
  • That didn't work... I'm wondering if it has something to do with ((AppCompatActivity)getActivity()), the fact that I have to find the activity before I can adjust the actonbar... maybe that's why the menu isn't working as intended... EDIT: Maybe I'll try inflating a new toolbar in the fragment... – Angel Mar 29 '16 at 21:57
  • paste the full code please, ill take a closer look. the code you provided in unsufficient – johnny_crq Mar 29 '16 at 22:05
  • Thank you for looking at this. I've added more code, that should show more of the fragment's lifecycle. – Angel Mar 29 '16 at 23:09
  • paste R.menu.eventcalendar_menu please – johnny_crq Mar 29 '16 at 23:38
  • oh is see know. The problem is that you are inflating a view for the searchView, but what you see is actually the default searchView and the inflated view is behind it. I'll update my answer – johnny_crq Mar 29 '16 at 23:53
  • i updated my answer. i copied a sample i had in an app of mine. The android.support.v7.appcompat.R.id.search_src_text is the default textView id and android.support.v7.appcompat.R.id.search_close_btn is the X button that appear to clean the view. let me know if that works for you – johnny_crq Mar 29 '16 at 23:58
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107673/discussion-between-user3806331-and-angel). – johnny_crq Mar 30 '16 at 00:02