#550 In-note-search doesn't jump to occurrence of searchstring

- Fix crash on pressing prev button too often
- Fix scrolling behavior in preview fragment
This commit is contained in:
stefan-niedermann 2020-01-23 08:58:27 +01:00
parent 4de492621b
commit 9b48acf182
4 changed files with 57 additions and 53 deletions

View file

@ -1,7 +1,7 @@
package it.niedermann.owncloud.notes.android.fragment;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ShortcutInfo;
@ -22,6 +22,7 @@ import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.ShareActionProvider;
@ -30,6 +31,7 @@ import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException;
import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException;
import com.nextcloud.android.sso.helper.SingleAccountHelper;
@ -131,14 +133,14 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
listener = (NoteFragmentListener) activity;
listener = (NoteFragmentListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(activity.getClass() + " must implement " + NoteFragmentListener.class);
throw new ClassCastException(context.getClass() + " must implement " + NoteFragmentListener.class);
}
db = NoteSQLiteOpenHelper.getInstance(activity);
db = NoteSQLiteOpenHelper.getInstance(context);
}
@Override
@ -160,7 +162,7 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
}
@Override
public void onSaveInstanceState(Bundle outState) {
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
saveNote(null);
outState.putSerializable(SAVEDKEY_NOTE, note);
@ -180,10 +182,10 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_note_fragment, menu);
if (isRequestPinShortcutSupported(getActivity()) && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (isRequestPinShortcutSupported(Objects.requireNonNull(getActivity())) && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
menu.add(Menu.NONE, MENU_ID_PIN, 110, R.string.pin_to_homescreen);
}
}
@ -191,7 +193,7 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
private int occurence = 1;
@Override
public void onPrepareOptionsMenu(Menu menu) {
public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem itemFavorite = menu.findItem(R.id.menu_favorite);
prepareFavoriteOption(itemFavorite);
@ -234,12 +236,18 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
View next = getSearchNextButton();
if (next != null) {
next.setOnClickListener(v -> jumpToNthNote(searchQuery, occurence, true));
next.setOnClickListener(v -> {
occurence++;
jumpToNthNote(searchQuery);
});
}
View prev = getSearchPrevButton();
if (prev != null) {
prev.setOnClickListener(v -> jumpToNthNote(searchQuery, occurence, false));
prev.setOnClickListener(v -> {
occurence--;
jumpToNthNote(searchQuery);
});
}
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@ -250,27 +258,27 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
@Override
public boolean onQueryTextChange(String newText) {
occurence = 1;
searchQuery = newText;
colorWithText(newText);
occurence = 1;
jumpToNthNote(newText);
return true;
}
});
}
private void jumpToNthNote(String newText) {
jumpToNthNote(newText, 1, true);
}
private void jumpToNthNote(String newText, int occurrence, boolean directionForward) {
if (newText == null || newText.isEmpty()) {
// No search term
return;
}
if (occurence < 1) {
// TODO find last occurence
occurence = 1;
return;
}
String currentContent = getContent().toLowerCase();
int indexOfNewText = indexOfNth(currentContent, newText.toLowerCase(), 0, occurrence);
int indexOfNewText = indexOfNth(currentContent, newText.toLowerCase(), 0, occurence);
if (indexOfNewText <= 0) {
// Search term not in text
occurence = 1;
@ -288,11 +296,6 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
if (numberLine >= 0) {
getScrollView().smoothScrollTo(0, getLayout().getLineTop(numberLine));
}
if(directionForward) {
this.occurence++;
} else {
this.occurence--;
}
}
private static int indexOfNth(String input, String value, int startIndex, int nth) {
@ -310,8 +313,9 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo
protected abstract Layout getLayout();
protected abstract View getSearchNextButton();
protected abstract View getSearchPrevButton();
protected abstract FloatingActionButton getSearchNextButton();
protected abstract FloatingActionButton getSearchPrevButton();
private void prepareFavoriteOption(MenuItem item) {
item.setIcon(note.isFavorite() ? R.drawable.ic_star_white_24dp : R.drawable.ic_star_border_white_24dp);

View file

@ -113,12 +113,12 @@ public class NoteEditFragment extends BaseNoteFragment {
}
@Override
protected View getSearchNextButton() {
protected FloatingActionButton getSearchNextButton() {
return searchNext;
}
@Override
protected View getSearchPrevButton() {
protected FloatingActionButton getSearchPrevButton() {
return searchPrev;
}

View file

@ -80,12 +80,12 @@ public class NotePreviewFragment extends BaseNoteFragment {
}
@Override
protected View getSearchNextButton() {
protected FloatingActionButton getSearchNextButton() {
return searchNext;
}
@Override
protected View getSearchPrevButton() {
protected FloatingActionButton getSearchPrevButton() {
return searchPrev;
}

View file

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.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:id="@+id/swiperefreshlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_normal"
tools:context="it.niedermann.owncloud.notes.android.activity.NotesListViewActivity"
tools:ignore="MergeRootFrame">
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swiperefreshlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="@color/bg_normal"
tools:context="it.niedermann.owncloud.notes.android.activity.NotesListViewActivity"
tools:ignore="MergeRootFrame">
<ScrollView
android:id="@+id/editContentContainer"
@ -30,20 +30,20 @@
android:textColor="@color/fg_default"
android:textIsSelectable="true" />
</ScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/searchPrev"
style="@style/fab"
android:layout_gravity="bottom|end"
android:translationY="-56dp"
app:fabSize="mini"
app:srcCompat="@drawable/ic_keyboard_arrow_up_white_24dp" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/searchPrev"
style="@style/fab"
android:layout_gravity="bottom|end"
android:translationY="-56dp"
app:fabSize="mini"
app:srcCompat="@drawable/ic_keyboard_arrow_up_white_24dp" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/searchNext"
style="@style/fab"
android:layout_gravity="bottom|end"
app:fabSize="mini"
app:srcCompat="@drawable/ic_keyboard_arrow_down_white_24dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/searchNext"
style="@style/fab"
android:layout_gravity="bottom|end"
app:fabSize="mini"
app:srcCompat="@drawable/ic_keyboard_arrow_down_white_24dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>