0

I'm currently dealing with AutoCompleteTextView, I think I set all the necessary stuffs, like the adapter, but when I type the dropdown menu is not shown. Here my code:

public class TouchEditText extends AutoCompleteTextView {

    TouchEditTextListener listener;
    private View root;
    private AutoCompleteTextView t;

    private Lexer lexer;
    private int currentStartLine;
    private int currentEndLine;
    private boolean modified;

    private final Handler handler = new Handler();
    private final Runnable updateAction =
            new Runnable()
            {
                @Override
                public void run()
                {
                    Editable e = getText();
                    highlightTextChanged(e);
                }
            };

    interface TouchEditTextListener {
        public void onTyped(String text);

    }


    public TouchEditText(Context context) {
        super(context);
        init(null, context);
    }

    public TouchEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, context);
    }

    public TouchEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, context);
    }

    private void init(AttributeSet attrs, Context context) {
        this.modified = true;
        this.setThreshold(1);
        t = this;
        setFilters(new InputFilter[]{new InputFilter() {
                    @Override
                    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend ) {
                        int indentationCount = 0;
                        if (source.length() != 0) {
                            if (source.charAt(source.length() - 1) == '\n') {
                                CharSequence line;
                                int currentLineNumber = getCurrentCursorLine();
                                int startPos = getLayout().getLineStart(currentLineNumber);
                                int endPos = getLayout().getLineEnd(currentLineNumber);

                                line = getText().subSequence(startPos, endPos);
                                indentationCount = 0;
                                for (char c : line.toString().toCharArray()) {
                                    if (c == ' ') {
                                        indentationCount++;
                                    } else {
                                        break;
                                    }
                                }

                                char last = line.charAt(line.length()-2);
                                if (last == '(' || last == '[' || last == '{') {
                                    indentationCount += 4;
                                }
                            }
                        }
                        String indentation = "";
                        for(int i = 0; i<indentationCount; i++) {
                            indentation += " ";
                        }
                        return source+indentation;
                    }
                }});

        ViewTreeObserver vto = getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                updateBoundaries();
                Editable highlighted = highlightText(getText());
                setText(highlighted);
            }
        });

        this.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                handler.removeCallbacks(updateAction);
                if(!modified) {
                    return;
                }
                listener.onTyped(getText().toString());
                handler.postDelayed(updateAction, 100);
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    public void setLexer(Lexer lexer) {
        this.lexer = lexer;
        List<String> allHints = new ArrayList<>();
        allHints.addAll(lexer.getPrimitiveTypesList());
        allHints.addAll(lexer.getKeywordsList());
        setHintsList(allHints);
    }

    //http://stackoverflow.com/questions/7627347/android-edittext-get-current-line
    private int getCurrentCursorLine()
    {
        int selectionStart = Selection.getSelectionStart(getText());
        Layout layout = getLayout();

        if (!(selectionStart == -1)) {
            return layout.getLineForOffset(selectionStart);
        }

        return -1;
    }

    private boolean updateBoundaries() {
        int height    = root.getHeight();
        int scrollY   = root.getScrollY();
        Layout layout = getLayout();
        int temp = currentStartLine;
        currentStartLine = layout.getLineForVertical(scrollY);
        currentEndLine  = layout.getLineForVertical(scrollY + height);
        return temp != currentStartLine;
    }

    public void setRoot(View root) {
        this.root = root;
    }

    private void highlightTextChanged(Editable e) {
        modified = false;
        highlightText(e);
        modified = true;
    }

    private void clearAllSpans(Editable editable) {
        {
            ForegroundColorSpan spans[] = editable.getSpans(0, editable.length(), ForegroundColorSpan.class);

            for(int n = spans.length; n-- > 0;) {
                editable.removeSpan(spans[n]);
            }
        }
    }

    public void setListener(TouchEditTextListener listener) {
        this.listener = listener;
    }

    public void initText(String content) {
        setText(content);
    }

    private Editable getVisibleText() {
        Editable content = new SpannableStringBuilder();
        for(int i = currentStartLine; i<=currentEndLine; i++) {
            content.append(getText().subSequence(getLayout().getLineStart(i), getLayout().getLineEnd(i)));
        }
        return content;
    }

    public Editable highlightText(Editable editable) {
        Editable visible = getVisibleText();
        clearAllSpans(editable);
        lexer.tokenize(editable, visible);
        return editable;
    }

    @Override
    protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {

        if(updateBoundaries()) {
            handler.removeCallbacks(updateAction);
            if(!modified) {
                return;
            }
            handler.postDelayed(updateAction, 1);

        }
    }

    public void forceSyntax(Syntax s) {
        lexer.forceSyntax(s);
        highlightText(getText());

    }

    private void setHintsList(List<String> hints) {
        String[] hintsArray = new String[hints.size()];
        for(int i = 0; i < hints.size(); i++) {
            hintsArray[i] = hints.get(i);
        }
        String[] a = {"if", "protected", "prot"};
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getContext(), android.R.layout.simple_dropdown_item_1line, hintsArray);
        this.setAdapter(adapter);
    }

I don't know if could be a problem that I manually set a TextChangedListener. Thank you

EDIT: Here the layout

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/codeScrollView"
    android:fillViewport="true">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:background="@drawable/lines_stroke"
            android:textColor="@android:color/white"
            android:text="@string/first_line"
            android:textSize="15dp"
            android:gravity="right"
            android:paddingLeft="15dp"
            android:paddingRight="5dp"
            android:id="@+id/edit_code_lines_view"/>

        <HorizontalScrollView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:fillViewport="true"
            android:scrollHorizontally="true" >

            <com.example.green.bachelorproject.customViews.codeEditView.TouchEditText
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@drawable/code_stroke"
                android:gravity="top"
                android:textColor="@android:color/white"
                android:textSize="15dp"
                android:inputType="textMultiLine|textNoSuggestions"
                android:paddingLeft="3dp"
                android:paddingRight="3dp"
                android:textCursorDrawable="@drawable/cursor_color"
                android:scrollHorizontally="true"
                android:id="@+id/edit_code_content_view"/>

        </HorizontalScrollView>



    </LinearLayout>
</ScrollView>

I was thinking that this line

android:inputType="textMultiLine|textNoSuggestions"

was causing the problem, but I removed it and still not working

Christopher A
  • 153
  • 1
  • 10

3 Answers3

1

I was having some similar issue and i found out a solution at this blog.

They are also using textchangedlistener() for populating the values from the listview that is containing the searched text. Have a look..

http://techinnovators.in/search-a-listview-on-search-box-value-in-android/

0

You call the setAdapter in SetHints. SetHints is called in SetLexer. But I don't think you actually call SetLexer (not in the coded you posted anyway).

  • `setLexer` is called in another object – Christopher A May 13 '15 at 14:36
  • What is `lexer.Tokenize` doing? Tokenizers are for `MultiAutoCompleteTextView`, and this is extending `AutoCompleteTextView` only. – David Kibblewhite May 13 '15 at 15:00
  • The tokenizer is just running a bunch of regex on the visible text to idenify syntactic elements like strings, comments, numbers and so on – Christopher A May 13 '15 at 15:07
  • I think the only thing you're doing different from me is the `TouchEditTextListener` you're setting. I only set a `TextWatcher` `this.addTextChangedListener(new TextWatcher()...`. As a test, if you don't set that listener does the auto complete work? – David Kibblewhite May 13 '15 at 15:15
0

Ok found the problem, actually seems that it's not getting what I just write, but the whole text. In fact, it will autocomplete only if there is the beginning of one of the suggestions.

EDIT

Actually my dropdown menu is showing one element at time and adds a scroll bar and the menu is shown on top of the EditText matching its width. Is there a way do move the menu near the autocompleted word (where the curso of the text is for example) and make the menu wrap the content? Thank you

Christopher A
  • 153
  • 1
  • 10