• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.documentsui.queries;
18 
19 import android.content.Context;
20 import android.os.Bundle;
21 import android.util.Log;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.view.ViewGroup;
25 import android.widget.AdapterView;
26 import android.widget.ArrayAdapter;
27 import android.widget.FrameLayout;
28 import android.widget.ListView;
29 import android.widget.TextView;
30 
31 import androidx.annotation.NonNull;
32 import androidx.annotation.Nullable;
33 import androidx.fragment.app.Fragment;
34 import androidx.fragment.app.FragmentManager;
35 import androidx.fragment.app.FragmentTransaction;
36 
37 import com.android.documentsui.BaseActivity;
38 import com.android.documentsui.Injector;
39 import com.android.documentsui.R;
40 
41 import java.util.List;
42 
43 public class SearchFragment extends Fragment {
44 
45     private static final String TAG = "SearchFragment";
46     private static final String KEY_QUERY = "query";
47     private static final int MAX_DISPLAY_ITEMS = 8;
48 
49     private SearchViewManager mSearchViewManager;
50 
51     private ViewGroup mSearchChipGroup;
52     private ListView mListView;
53     private ArrayAdapter<String> mAdapter;
54 
55     private List<String> mHistoryList;
56 
showFragment(FragmentManager fm, String initQuery)57     public static void showFragment(FragmentManager fm, String initQuery) {
58         if (fm.isStateSaved()) {
59             Log.w(TAG, "Skip show because state saved");
60             return;
61         }
62 
63         final SearchFragment fragment = new SearchFragment();
64         final Bundle args = new Bundle();
65         args.putString(KEY_QUERY, initQuery);
66         fragment.setArguments(args);
67 
68         final FragmentTransaction ft = fm.beginTransaction();
69         ft.replace(getFragmentId(), fragment, TAG);
70         ft.commitNow();
71     }
72 
dismissFragment(FragmentManager fm)73     public static void dismissFragment(FragmentManager fm) {
74         SearchFragment fragment = get(fm);
75         if (fragment != null && fragment.getActivity() != null) {
76             fragment.dismiss();
77         }
78     }
79 
get(FragmentManager fm)80     public static SearchFragment get(FragmentManager fm) {
81         final Fragment fragment = fm.findFragmentByTag(TAG);
82         return fragment instanceof SearchFragment
83                 ? (SearchFragment) fragment
84                 : null;
85     }
86 
87     @Nullable
88     @Override
onCreateView(@onNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)89     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
90             @Nullable Bundle savedInstanceState) {
91         final View view = inflater.inflate(R.layout.fragment_search, container, false);
92 
93         mSearchChipGroup = view.findViewById(R.id.search_chip_group);
94         mListView = view.findViewById(R.id.history_list);
95 
96         return view;
97     }
98 
99     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)100     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
101         super.onViewCreated(view, savedInstanceState);
102 
103         final BaseActivity activity = (BaseActivity) getActivity();
104         final Injector injector = activity.getInjector();
105         mSearchViewManager = injector.searchManager;
106         mSearchViewManager.setFragmentManager(this.getParentFragmentManager());
107 
108         final String currentQuery = getArguments().getString(KEY_QUERY, "");
109 
110         mHistoryList = SearchHistoryManager.getInstance(
111                 getContext().getApplicationContext()).getHistoryList(currentQuery);
112 
113         mSearchViewManager.bindChips(mSearchChipGroup);
114         if (mSearchChipGroup.getVisibility() == View.VISIBLE) {
115             for (int i = 0, size = mSearchChipGroup.getChildCount(); i < size; i++) {
116                 mSearchChipGroup.getChildAt(i).setOnClickListener(this::onChipClicked);
117             }
118         }
119 
120         mAdapter = new HistoryListAdapter(getContext(), mHistoryList);
121         mListView.setAdapter(mAdapter);
122         mListView.setOnItemClickListener(this::onHistoryItemClicked);
123 
124         View toolbar = getActivity().findViewById(R.id.toolbar);
125         View collapsingBarLayout = getActivity().findViewById(R.id.collapsing_toolbar);
126         if (toolbar != null && collapsingBarLayout != null) {
127             // If collapsingBarLayout is used (i.e. not in Tablet mode),
128             // need to align top with the bottom of search bar.
129             FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
130                     ViewGroup.LayoutParams.MATCH_PARENT,
131                     ViewGroup.LayoutParams.MATCH_PARENT);
132             layoutParams.setMargins(0, getResources().getDimensionPixelSize(
133                     R.dimen.action_bar_margin) + toolbar.getLayoutParams().height, 0, 0);
134             getView().setLayoutParams(layoutParams);
135         }
136 
137         updateDirectoryVisibility(View.GONE);
138     }
139 
getFragmentId()140     private static int getFragmentId() {
141         return R.id.container_search_fragment;
142     }
143 
onChipClicked(View view)144     private void onChipClicked(View view) {
145         final Object tag = view.getTag();
146         if (tag instanceof SearchChipData) {
147             mSearchViewManager.onMirrorChipClick((SearchChipData) tag);
148         }
149     }
150 
onHistoryItemClicked(AdapterView<?> parent, View view, int position, long id)151     private void onHistoryItemClicked(AdapterView<?> parent, View view, int position, long id) {
152         final String item = mHistoryList.get(position);
153         mSearchViewManager.setHistorySearch();
154         mSearchViewManager.setCurrentSearch(item);
155         mSearchViewManager.restoreSearch(/* keepFocus= */ false);
156     }
157 
dismiss()158     private void dismiss() {
159         if (getActivity() == null) {
160             // Fragment has already been detached from activity.
161             return;
162         }
163 
164         updateDirectoryVisibility(View.VISIBLE);
165 
166         FragmentTransaction ft = getParentFragmentManager().beginTransaction();
167         ft.remove(this);
168         ft.commitNow();
169     }
170 
updateDirectoryVisibility(int visibility)171     private void updateDirectoryVisibility(int visibility) {
172         View directoryHeader = getActivity().findViewById(R.id.directory_header);
173         if (directoryHeader != null) {
174             directoryHeader.setVisibility(visibility);
175         }
176 
177         View directoryContainer = getActivity().findViewById(R.id.container_directory);
178         if (directoryContainer != null) {
179             directoryContainer.setVisibility(visibility);
180         }
181     }
182 
183     private class HistoryListAdapter extends ArrayAdapter<String> {
184 
HistoryListAdapter(Context context, List<String> list)185         public HistoryListAdapter(Context context, List<String> list) {
186             super(context, R.layout.item_history, list);
187         }
188 
189         @Override
getView(int position, View convertView, ViewGroup parent)190         public View getView(int position, View convertView, ViewGroup parent) {
191             if (convertView == null) {
192                 convertView = getLayoutInflater().inflate(R.layout.item_history, parent, false);
193             }
194             final String history = getItem(position);
195             final TextView text = convertView.findViewById(android.R.id.title);
196             final View button = convertView.findViewById(android.R.id.icon);
197 
198             text.setText(history);
199             button.setOnClickListener(v -> {
200                 mSearchViewManager.removeHistory(history);
201                 mHistoryList.remove(history);
202                 notifyDataSetChanged();
203             });
204             button.setContentDescription(
205                     getContext().getString(R.string.delete_search_history, history));
206 
207             return convertView;
208         }
209 
210         @Override
getCount()211         public int getCount() {
212             final int count = super.getCount();
213             return count > MAX_DISPLAY_ITEMS ? MAX_DISPLAY_ITEMS : count;
214         }
215     }
216 }
217