Skip to content
Guides

Custom Menu

When viewing a PDF, selecting text and long-pressing in a blank area triggers the corresponding interactive state in the PDF context. In each interactive state, a context menu similar to a "Menu" will appear, allowing you to perform relevant actions through the menu options.

This example shows how to use an additional context menu that appears when text is selected and a long press is applied to a blank area:

t_markup_annot_menu_layout.xml:

xml
<?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="match_parent"
    android:background="@drawable/bg_context_menu_window"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/attr"
				android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
        android:text="attribute" />

    <TextView
        android:id="@+id/copy"
        android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
        android:text="copy" />

    <TextView
        android:id="@+id/delete"
        android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
        android:text="@string/delete" />

</LinearLayout>
Java
public class TContextMenuHelper extends CPDFContextMenuShowHelper {
	...
	@Override
  public View getMarkupContentView(CPDFPageView pageView, CPDFBaseAnnotImpl annotImpl, LayoutInflater layoutInflater) {
        View contentView = layoutInflater.inflate(R.layout.t_markup_annot_menu_layout, null);
        CPDFMarkupAnnotImpl markupAnnotImpl = (CPDFMarkupAnnotImpl) annotImpl;
        CPDFMarkupAnnotation markupAnnotation = markupAnnotImpl.onGetAnnotation();
        invokeOnClickListener(contentView, v -> {
            int id = v.getId();
            if (id == R.id.attr) {
                markupAnnotation.setColor(Color.RED);
                markupAnnotation.setAlpha(100);
                markupAnnotation.updateAp();
                markupAnnotImpl.onAnnotAttrChange();
                pageView.invalidate();
            } else if (id == R.id.copy) {
                String markedText = markupAnnotation.getMarkedText();
                if (!TextUtils.isEmpty(markedText)) {
                    CPDFTextUtils.setClipData(context, "ComPDFKit", markedText);
                }
                return;
            } else if (id == R.id.delete) {
                pageView.deleteAnnotation(annotImpl);
            }
            popupWindow.dismiss();
        }, R.id.attr, R.id.copy, R.id.delete);
        return contentView;
    }
  
	@Override
  public View getInkContentView(CPDFPageView pageView, CPDFBaseAnnotImpl annotImpl, LayoutInflater layoutInflater) {
        View contentView = layoutInflater.inflate(R.layout.t_markup_annot_menu_layout, null);

        CPDFInkAnnotImpl inkAnnotImpl = (CPDFInkAnnotImpl) annotImpl;
        CPDFInkAnnotation inkAnnotation = (CPDFInkAnnotation) inkAnnotImpl.onGetAnnotation();
        invokeOnClickListener(contentView, v -> {
            int id = v.getId();
            if (id == R.id.attr) {
                inkAnnotation.setColor(Color.RED);
                inkAnnotation.setAlpha(100);
                inkAnnotation.setBorderWidth(5);
                inkAnnotation.updateAp();
                inkAnnotImpl.onAnnotAttrChange();
                pageView.invalidate();
            } else if (id == R.id.delete) {
                pageView.deleteAnnotation(annotImpl);
            }
            popupWindow.dismiss();
        }, R.id.attr, R.id.delete);
        return contentView;
    }
	...

}
kotlin
class TContextMenuHelper(readerView: CPDFReaderView?) : CPDFContextMenuShowHelper(readerView) {
    override fun getMarkupContentView(pageView: CPDFPageView, annotImpl: CPDFBaseAnnotImpl<*>, layoutInflater: LayoutInflater): View {
        val contentView = layoutInflater.inflate(R.layout.t_markup_annot_menu_layout, null)
        val markupAnnotImpl = annotImpl as CPDFMarkupAnnotImpl
        val markupAnnotation = markupAnnotImpl.onGetAnnotation()
        invokeOnClickListener(contentView, { v ->
            val id = v.id
            when (id) {
                R.id.attr -> {
                    markupAnnotation.color = Color.RED
                    markupAnnotation.alpha = 100
                    markupAnnotation.updateAp()
                    markupAnnotImpl.onAnnotAttrChange()
                    pageView.invalidate()
                }
                R.id.copy -> {
                    val markedText = markupAnnotation.markedText
                    if (markedText.isNotEmpty()) {
                        CPDFTextUtils.setClipData(context, "ComPDFKit", markedText)
                    }
                }
                R.id.delete -> pageView.deleteAnnotation(annotImpl)
            
            }
            popupWindow.dismiss()
        }, R.id.attr, R.id.copy, R.id.delete)
        return contentView
    }

    override fun getInkContentView(pageView: CPDFPageView, annotImpl: CPDFBaseAnnotImpl<*>, layoutInflater: LayoutInflater): View {
        val contentView = layoutInflater.inflate(R.layout.t_markup_annot_menu_layout, null)
        val inkAnnotImpl = annotImpl as CPDFInkAnnotImpl
        val inkAnnotation = inkAnnotImpl.onGetAnnotation() as CPDFInkAnnotation
        invokeOnClickListener(contentView, { v ->
            val id = v.id
            when (id) {
                R.id.attr -> {
                    inkAnnotation.color = Color.RED
                    inkAnnotation.alpha = 100
                    inkAnnotation.borderWidth = 5F
                    inkAnnotation.updateAp()
                    inkAnnotImpl.onAnnotAttrChange()
                    pageView.invalidate()
                }
                R.id.delete -> pageView.deleteAnnotation(annotImpl)
            }
            popupWindow.dismiss()
        }, R.id.attr, R.id.delete)
        return contentView
    }
}