Browse Source

ComPDFKit Tools(Android) - search接上数据

libai 1 year ago
parent
commit
f21d37ac8e

+ 114 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/search/CSearchResultBottomSheetDialogFragment.java

@@ -0,0 +1,114 @@
+package com.compdfkit.tools.search;
+
+import android.annotation.SuppressLint;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.utils.dialog.DialogFragmentUtil;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+
+import java.util.List;
+
+public class CSearchResultBottomSheetDialogFragment extends BottomSheetDialogFragment {
+    private View mContentView;
+    private View backImage;
+    private RecyclerView recyclerView;
+
+    private List<CSearchTextInfo> searchTextInfos = null;
+    private SearchTextRecyclerviewAdapter searchTextAdapter;
+private SearchTextRecyclerviewAdapter.OnClickSearchItemListener onClickSearchItemListener;
+//    public CSearchResultBottomSheetDialogFragment() {
+//
+//    }
+
+ //   public CSearchResultBottomSheetDialogFragment(int contentLayoutId) {
+ //       super(contentLayoutId);
+ //   }
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.e("ff","bbbbb oncreate");
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        BottomSheetBehavior<View> behavior = BottomSheetBehavior.from((View) getView().getParent());
+        DialogFragmentUtil.setBottomSheetDialogFragmentFullScreen(getDialog(), behavior);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        Log.e("ff","bbbbb oncreat view");
+        return inflater.inflate(R.layout.search_result, container, false);
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        mContentView = view;
+        Log.e("ff","bbbbb oncreate d");
+        initView();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+//    @SuppressLint("RestrictedApi")
+//    @Override
+//    public void setupDialog(@NonNull Dialog dialog, int style) {
+//        super.setupDialog(dialog, style);
+//        mContentView = View.inflate(getContext(), R.layout.search_result, null);
+//        dialog.setContentView(mContentView);
+//        initView();
+//    }
+
+    private void initView() {
+        backImage = mContentView.findViewById(R.id.id_reader_search_back);
+        recyclerView = mContentView.findViewById(R.id.id_reader_search_recyclerView);
+        LinearLayoutManager layoutManager = new LinearLayoutManager(recyclerView.getContext());
+        recyclerView.setLayoutManager(layoutManager);
+        searchTextAdapter = new SearchTextRecyclerviewAdapter();
+        recyclerView.setAdapter(searchTextAdapter);
+        if (null != searchTextInfos) {
+            searchTextAdapter.clearList();
+            searchTextAdapter.addList(searchTextInfos);
+            searchTextAdapter.notifyDataSetChanged();
+        }
+        backImage.setOnClickListener(view -> {
+            dismiss();
+        });
+        searchTextAdapter.setOnClickSearchItemListener(onClickSearchItemListener);
+    }
+
+    public void setSearchTextInfos(List<CSearchTextInfo> searchTextInfos) {
+        this.searchTextInfos = searchTextInfos;
+        if (null != searchTextAdapter) {
+            searchTextAdapter.clearList();
+            searchTextAdapter.addList(searchTextInfos);
+            searchTextAdapter.notifyDataSetChanged();
+        }
+    }
+
+    public void setOnClickSearchItemListener(SearchTextRecyclerviewAdapter.OnClickSearchItemListener listener) {
+        onClickSearchItemListener = listener;
+        if (null != searchTextAdapter) {
+            searchTextAdapter.setOnClickSearchItemListener(listener);
+        }
+    }
+}

+ 82 - 7
compdfkit-tools/src/main/java/com/compdfkit/tools/search/CSearchToolbar.java

@@ -1,26 +1,44 @@
 package com.compdfkit.tools.search;
 
 import android.content.Context;
+import android.graphics.Color;
+import android.os.AsyncTask;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
+import android.widget.TextView;
 
+import com.compdfkit.core.document.CPDFDocument;
+import com.compdfkit.core.page.CPDFPage;
+import com.compdfkit.core.page.CPDFTextPage;
+import com.compdfkit.core.page.CPDFTextRange;
+import com.compdfkit.core.page.CPDFTextSearcher;
 import com.compdfkit.tools.R;
+import com.compdfkit.ui.reader.CPDFReaderView;
+import com.compdfkit.ui.textsearch.ITextSearcher;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 public class CSearchToolbar extends RelativeLayout implements View.OnClickListener {
-    private Button completeBt;
+    private TextView completeBt;
     private EditText searchEdit;
     private ImageView leftImage;
     private ImageView rightImage;
     private ImageView listImage;
 
-    private Context context;
+    private Context mContext;
+
+    private CPDFReaderView readerView;
+    private ITextSearcher textSearcher;
+    private CPDFDocument tpdfDocument;
 
     OnSearchListener onSearchListener = null;
     List<CSearchTextInfo> searchTextInfos = null;
@@ -46,8 +64,10 @@ public class CSearchToolbar extends RelativeLayout implements View.OnClickListen
     }
 
     private void init(Context context) {
-        this.context = context;
+        this.mContext = context;
         inflate(context, R.layout.search_toolbar, this);
+        setBackgroundColor(Color.WHITE);
+        setElevation(8);
         completeBt = findViewById(R.id.complete);
         searchEdit = findViewById(R.id.search_word);
         leftImage = findViewById(R.id.left);
@@ -57,14 +77,58 @@ public class CSearchToolbar extends RelativeLayout implements View.OnClickListen
         leftImage.setOnClickListener(this);
         rightImage.setOnClickListener(this);
     }
+    Lock lock = new ReentrantLock();
+    private AsyncTask<Void, Void, Boolean> searchTask;
+
+    private void cancelTask() {
+        try {
+            lock.lock();
+            if (searchTextInfos != null) {
+                searchTextInfos.clear();
+            }
+            if (searchTask != null && !searchTask.isCancelled()) {
+                searchTask.cancel(true);
+            }
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    private void startSearch() {
+        final String search = searchEdit.getText().toString();
+        if (null != onSearchListener && !TextUtils.isEmpty(search)) {
+            cancelTask();
+            searchTask = new AsyncTask<Void, Void, Boolean>() {
+                @Override
+                protected void onPreExecute() {
+                    super.onPreExecute();
+                }
+
+                @Override
+                protected Boolean doInBackground(Void... voids) {
+                    if (null != onSearchListener) {
+                        searchTextInfos = onSearchListener.onStartSearch(search);
+                    }
+                    return true;
+                }
+
+                @Override
+                protected void onPostExecute(Boolean aBoolean) {
+                    super.onPostExecute(aBoolean);
+                    if (null != onSearchListener) {
+                        onSearchListener.onEndSearch(searchTextInfos);
+                    }
+                }
+            };
+            searchTask.execute();
+        }
+    }
 
     @Override
     public void onClick(View view) {
         int id = view.getId();
         if (id == R.id.complete) {
-            if (null != onSearchListener && (!TextUtils.isEmpty(searchEdit.getText().toString()))) {
-                searchTextInfos = onSearchListener.onSearch(searchEdit.getText().toString());
-            }
+            startSearch();
         } else if (id == R.id.left) {
 
         } else if (id == R.id.right) {
@@ -74,11 +138,22 @@ public class CSearchToolbar extends RelativeLayout implements View.OnClickListen
         }
     }
 
+
+
     public void setSearchListener(OnSearchListener onSearchListener) {
         this.onSearchListener = onSearchListener;
     }
 
+    public void setReaderView(CPDFReaderView readerView) {
+        if (null != readerView) {
+            this.readerView = readerView;
+            this.textSearcher = readerView.getTextSearcher();
+            tpdfDocument = readerView.getPDFDocument();
+        }
+    }
+
     public interface OnSearchListener {
-        List<CSearchTextInfo> onSearch(String word);
+        List<CSearchTextInfo> onStartSearch(String word);
+        void onEndSearch(List<CSearchTextInfo> searchResult);
     }
 }

+ 117 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/search/SearchTextRecyclerviewAdapter.java

@@ -0,0 +1,117 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+ * This notice may not be removed from this file.
+ */
+package com.compdfkit.tools.search;
+
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.compdfkit.tools.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchTextRecyclerviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+    /****** 头部 ******/
+    private final static int ITEM_TYPE_HEAD = 0x100;
+    /****** 搜索的内容 ******/
+    private final static int ITEM_TYPE_CONTENT = 0x200;
+    private final List<CSearchTextInfo> searchTextInfoList;
+
+    private OnClickSearchItemListener onClickSearchItemListener;
+
+    public SearchTextRecyclerviewAdapter() {
+        this.searchTextInfoList = new ArrayList<>();
+    }
+
+    public void addItem(CSearchTextInfo item) {
+        searchTextInfoList.add(item);
+    }
+
+    public void addList(List<CSearchTextInfo> list) {
+        searchTextInfoList.addAll(list);
+    }
+
+    public void clearList() {
+        searchTextInfoList.clear();
+    }
+
+    public void setOnClickSearchItemListener(OnClickSearchItemListener onClickSearchItemListener) {
+        this.onClickSearchItemListener = onClickSearchItemListener;
+    }
+
+    @NonNull
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        if (ITEM_TYPE_HEAD == viewType) {
+            return new SearchTextHeadViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_search_text_header, parent, false));
+        }
+        return new SearchTextContentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_search_text_content, parent, false));
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (searchTextInfoList != null && searchTextInfoList.size() > 0) {
+            if (searchTextInfoList.get(position).isHeader) {
+                return ITEM_TYPE_HEAD;
+            }
+        }
+        return ITEM_TYPE_CONTENT;
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
+        final int adapterPosition = holder.getAdapterPosition();
+        if (searchTextInfoList != null && searchTextInfoList.size() > 0) {
+            if (holder instanceof SearchTextHeadViewHolder) {
+                ((SearchTextHeadViewHolder) holder).idItemSearchHeadPage.setText(String.valueOf(searchTextInfoList.get(adapterPosition).page + 1));
+            } else {
+                ((SearchTextContentViewHolder) holder).idItemSearchContentText.setText(searchTextInfoList.get(adapterPosition).stringBuilder);
+                ((SearchTextContentViewHolder) holder).idItemSearchContentText.setOnClickListener(v -> {
+                    CSearchTextInfo clickItem = searchTextInfoList.get(adapterPosition);
+                    if (onClickSearchItemListener != null) {
+                        onClickSearchItemListener.onClick(clickItem);
+                    }
+                });
+            }
+        }
+    }
+
+    @Override
+    public int getItemCount() {
+        return searchTextInfoList.size();
+    }
+
+    public static class SearchTextHeadViewHolder extends RecyclerView.ViewHolder {
+        private TextView idItemSearchHeadPage;
+
+        public SearchTextHeadViewHolder(View itemView) {
+            super(itemView);
+            idItemSearchHeadPage = itemView.findViewById(R.id.id_item_search_head_page);
+        }
+    }
+
+    public static class SearchTextContentViewHolder extends RecyclerView.ViewHolder {
+        private TextView idItemSearchContentText;
+
+        public SearchTextContentViewHolder(View itemView) {
+            super(itemView);
+            idItemSearchContentText = itemView.findViewById(R.id.id_item_search_content_text);
+        }
+    }
+
+    public interface OnClickSearchItemListener {
+        void onClick(CSearchTextInfo clickItem);
+    }
+}

+ 12 - 0
compdfkit-tools/src/main/res/drawable/search_edit_bg.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle" >
+
+    <!-- 圆角弧度 15 -->
+    <corners android:radius="1dp"/>
+
+    <solid android:color="@color/white_color"/>
+    <stroke android:width="1px"
+            android:color="@color/border_color"/>
+
+</shape>

+ 9 - 0
compdfkit-tools/src/main/res/drawable/svg_ic_left_arrow.xml

@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="1024"
+    android:viewportHeight="1024">
+  <path
+      android:pathData="M474.5,512l338.75,-338.75 -90.5,-90.5L293.5,512l429.25,429.25 90.5,-90.5z"
+      android:fillColor="#000000"/>
+</vector>

+ 9 - 0
compdfkit-tools/src/main/res/drawable/svg_ic_right_arrow.xml

@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="1024"
+    android:viewportHeight="1024">
+  <path
+      android:pathData="M613.5,512L274.75,173.25l90.5,-90.5L794.5,512l-429.25,429.25 -90.5,-90.5z"
+      android:fillColor="#000000"/>
+</vector>

+ 25 - 0
compdfkit-tools/src/main/res/layout/item_search_text_content.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/qb_px_64">
+    <TextView
+        android:id="@+id/id_item_search_content_text"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/qb_px_32"
+        android:maxLines="3"
+        android:minLines="3"
+        android:textColor="@color/search_result_text_color"
+        android:textSize="@dimen/qb_px_12"
+        android:layout_marginLeft="@dimen/qb_px_16"
+        android:layout_marginRight="@dimen/qb_px_16"
+        android:layout_marginTop="@dimen/qb_px_16"/>
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/qb_px_1"
+        android:background="#1a000000"
+        android:layout_alignParentBottom="true"
+        android:layout_marginLeft="@dimen/qb_px_16"
+        android:layout_marginRight="@dimen/qb_px_16"/>
+
+</RelativeLayout>

+ 25 - 0
compdfkit-tools/src/main/res/layout/item_search_text_header.xml

@@ -0,0 +1,25 @@
+<?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="@dimen/qb_px_24"
+    android:background="@color/search_result_text_item_bg">
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/search_header_page"
+        android:layout_marginLeft="@dimen/qb_px_15"
+        android:textSize="@dimen/qb_px_12"
+        android:layout_gravity="center"/>
+    <View
+        android:layout_width="@dimen/qb_px_5"
+        android:layout_height="match_parent"/>
+    <TextView
+        android:id="@+id/id_item_search_head_page"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="@dimen/qb_px_12"
+        android:layout_gravity="center"
+        android:text="10"/>
+
+</LinearLayout>

+ 37 - 0
compdfkit-tools/src/main/res/layout/search_result.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/white_color">
+
+    <RelativeLayout
+        android:id="@+id/id_search_head"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/qb_px_56"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true"
+        android:background="@color/reader_tools_button_normal">
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/id_reader_search_back"
+            android:layout_width="@dimen/qb_px_50"
+            android:layout_height="match_parent"
+            android:layout_alignParentLeft="true"
+            android:background="@color/reader_tools_button_normal"
+            android:src="@drawable/tool_button_click" />
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/id_search_msg"
+            android:layout_centerHorizontal="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"/>
+
+    </RelativeLayout>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/id_reader_search_recyclerView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@+id/id_search_head" />
+
+</RelativeLayout>

+ 34 - 8
compdfkit-tools/src/main/res/layout/search_toolbar.xml

@@ -1,26 +1,52 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <Button
+    <TextView
         android:id="@+id/complete"
+        android:layout_alignParentLeft="true"
+        android:layout_centerVertical="true"
+        android:layout_marginLeft="@dimen/qb_px_15"
+        android:textColor="@color/search_text"
+        android:text="@string/search_complete"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>
     <EditText
         android:id="@+id/search_word"
-        android:layout_width="@dimen/qb_px_60"
-        android:layout_height="wrap_content"/>
+        android:hint="ddddjjjjjfff"
+        android:layout_marginLeft="@dimen/qb_px_10"
+        android:layout_toRightOf="@+id/complete"
+        android:background="@drawable/search_edit_bg"
+        android:layout_marginRight="@dimen/qb_px_20"
+        android:layout_centerVertical="true"
+        android:layout_width="@dimen/qb_px_120"
+        android:layout_height="@dimen/qb_px_30"/>
+
     <ImageView
-        android:id="@+id/left"
+        android:id="@+id/list"
+        android:layout_alignParentRight="true"
+        android:background="@drawable/tools_ic_more"
+        android:layout_marginRight="@dimen/qb_px_10"
+        android:layout_centerVertical="true"
         android:layout_width="@dimen/qb_px_30"
         android:layout_height="@dimen/qb_px_30"/>
+
     <ImageView
-        android:id="@+id/right"
+        android:id="@+id/left"
+        android:background="@drawable/svg_ic_right_arrow"
+        android:layout_marginRight="@dimen/qb_px_10"
+        android:layout_toLeftOf="@+id/list"
+        android:layout_centerVertical="true"
         android:layout_width="@dimen/qb_px_30"
         android:layout_height="@dimen/qb_px_30"/>
     <ImageView
-        android:id="@+id/list"
+        android:id="@+id/right"
+        android:layout_toLeftOf="@+id/left"
+        android:layout_marginRight="@dimen/qb_px_10"
+        android:background="@drawable/svg_ic_left_arrow"
+        android:layout_centerVertical="true"
         android:layout_width="@dimen/qb_px_30"
         android:layout_height="@dimen/qb_px_30"/>
-</LinearLayout>
+
+</RelativeLayout>

+ 4 - 0
compdfkit-tools/src/main/res/values/colors.xml

@@ -5,4 +5,8 @@
     <color name="reader_tools_button_clicked">#1E0071EE</color>
     <color name="search_result_text_color">#333333</color>
     <color name="search_result_text_highlight">#FFAB00</color>
+    <color name="search_result_text_item_bg">#E8E8E8</color>
+    <color name="white_color">#ffffff</color>
+    <color name="search_text">#007ACC</color>
+    <color name="border_color">#ff999999</color>
 </resources>

+ 2 - 0
compdfkit-tools/src/main/res/values/strings.xml

@@ -4,4 +4,6 @@
     <string name="goto_page_dialog_title">Go To Page</string>
     <string name="goto_page_dialog_msg">Enter a page number</string>
     <string name="goto_page_dialog_hint">input page</string>
+    <string name="search_header_page">Page</string>
+    <string name="search_complete">完成</string>
 </resources>

+ 77 - 9
viewer-ctrl-demo/src/main/java/com/compdfkit/demo/viewer/MainActivity.java

@@ -3,13 +3,29 @@ package com.compdfkit.demo.viewer;
 import androidx.appcompat.app.AppCompatActivity;
 
 import android.os.Bundle;
+import android.util.Log;
 import android.widget.Toast;
 
+import com.compdfkit.core.document.CPDFDocument;
+import com.compdfkit.core.page.CPDFPage;
+import com.compdfkit.core.page.CPDFTextPage;
+import com.compdfkit.core.page.CPDFTextRange;
+import com.compdfkit.core.page.CPDFTextSearcher;
 import com.compdfkit.demo.viewer.databinding.ViewerActivityMainBinding;
 import com.compdfkit.tools.pdfbota.pdfoutline.CPDFOutlineDialogFragment;
 import com.compdfkit.tools.pdfbota.pdfoutline.bean.COutlineData;
 import com.compdfkit.tools.pdfbota.pdfoutline.data.CPDFOutlineDatas;
+import com.compdfkit.tools.dialog.CGotoPageDialog;
+import com.compdfkit.tools.search.CSearchResultBottomSheetDialogFragment;
+import com.compdfkit.tools.search.CSearchTextInfo;
+import com.compdfkit.tools.search.CSearchToolbar;
+import com.compdfkit.tools.search.SearchTextRecyclerviewAdapter;
 import com.compdfkit.tools.task.CExtractAssetFileTask;
+import com.compdfkit.ui.reader.CPDFReaderView;
+import com.compdfkit.ui.textsearch.ITextSearcher;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import java.util.ArrayList;
 
@@ -28,10 +44,9 @@ public class MainActivity extends AppCompatActivity {
         binding = ViewerActivityMainBinding.inflate(getLayoutInflater());
         setContentView(binding.getRoot());
         initToolbarListener();
+        intSearchBarListener();
         CExtractAssetFileTask.extract(this, QUICK_START_GUIDE, QUICK_START_GUIDE, (pdfFile) ->
                 runOnUiThread(() -> binding.pdfReaderView.openPdfFile(pdfFile.getAbsolutePath())));
-
-
     }
 
 
@@ -53,13 +68,66 @@ public class MainActivity extends AppCompatActivity {
         binding.pdfToolBar.setMoreBtnClickListener(v -> {
 
         });
-
+    }
+    private void intSearchBarListener() {
+        binding.pdfSearchToolBar.setSearchListener(new CSearchToolbar.OnSearchListener() {
+            @Override
+            public List<CSearchTextInfo> onStartSearch(String word) {
+                return startSearch(word, binding.pdfReaderView.getCPdfReaderView());
+            }
+
+            @Override
+            public void onEndSearch(List<CSearchTextInfo> searchResult) {
+                CSearchResultBottomSheetDialogFragment searchResultDialog = new CSearchResultBottomSheetDialogFragment();
+                searchResultDialog.show(getSupportFragmentManager(), "search");
+                searchResultDialog.setSearchTextInfos(searchResult);
+                searchResultDialog.setOnClickSearchItemListener(new SearchTextRecyclerviewAdapter.OnClickSearchItemListener() {
+                    @Override
+                    public void onClick(CSearchTextInfo clickItem) {
+                        binding.pdfReaderView.getCPdfReaderView().setDisplayPageIndex(clickItem.page);
+                        binding.pdfReaderView.getCPdfReaderView().getTextSearcher().searchBegin(clickItem.page, clickItem.textRangeIndex);
+                        searchResultDialog.dismiss();
+                    }
+                });
+            }
+        });
+    }
+    private List<CSearchTextInfo> startSearch(String searchWord, CPDFReaderView readerView) {
+        if (null == readerView || !(readerView instanceof CPDFReaderView)) {
+            return null;
+        }
+        ITextSearcher textSearcher = readerView.getTextSearcher();
+        if (null == textSearcher) {
+            return null;
+        }
+        CPDFDocument document = readerView.getPDFDocument();
+        if (null == document) {
+            return null;
+        }
+        textSearcher.setSearchConfig(searchWord, CPDFTextSearcher.PDFSearchOptions.PDFSearchCaseInsensitive);
+        List<CSearchTextInfo> searchTextInfoList = new ArrayList<>();
+        for (int i = 0; i < document.getPageCount(); i++) {
+            CPDFPage page = document.pageAtIndex(i);
+            CPDFTextPage textPage = page.getTextPage();
+            if((null == textPage) || !textPage.isValid()) continue;
+            final List<CSearchTextInfo> searchPageContent = findSearchText(textSearcher, textPage, searchWord, i);
+            if (searchPageContent.size() > 0) {
+                final int searchPageNum = i;
+                final CSearchTextInfo pageTextInfo = new CSearchTextInfo(this, searchPageNum, searchWord, null, null, 0, true);
+                searchTextInfoList.add(pageTextInfo);
+                searchTextInfoList.addAll(searchPageContent);
+            }
+            page.close();
+        }
+        return searchTextInfoList;
     }
 
-
-
-
-
-
-
+    private List<CSearchTextInfo> findSearchText(ITextSearcher textSearcher, CPDFTextPage textPage, String keyword, int page) {
+        ArrayList<CPDFTextRange> textRanges = textSearcher.searchKeyword(page);
+        ArrayList<CSearchTextInfo> searchTextInfos = new ArrayList<>(textRanges.size());
+        for (int i = 0; i < textRanges.size(); i++) {
+            searchTextInfos.add(new CSearchTextInfo(this, page, keyword, textPage, textRanges.get(i), i, false));
+        }
+        return searchTextInfos;
+    }
 }

+ 11 - 0
viewer-ctrl-demo/src/main/res/layout/viewer_activity_main.xml

@@ -17,6 +17,17 @@
         app:tools_toolbar_title="@string/viewer_toolbar_title"
         />
 
+    <com.compdfkit.tools.search.CSearchToolbar
+        android:id="@+id/pdf_search_tool_bar"
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/actionBarSize"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:tools_toolbar_title="@string/viewer_toolbar_title"
+        android:visibility="gone"
+        />
+
     <com.compdfkit.tools.pdfview.CPDFReaderView
         android:id="@+id/pdf_reader_view"
         android:layout_width="match_parent"