8

私は Android のリッチ テキスト エディターに取り組んでいます。基本的に、コンテンツのスタイルを変更するための EditText に関連付けられた太字、斜体、およびリンク ボタンがあります。最初にスタイルを設定するテキストを選択してから、このメソッドを使用してボタンを選択すると、うまく機能します: http://developer.android.com/guide/appendix/faq/commontasks.html#selectingtext .

私がやろうとしているのは、リッチ テキスト エディターのように機能するようにすることです。ボタンをトグルとして使用して、テキストのスタイルを設定し、トグルをもう一度クリックして、スタイルの使用を停止します。したがって、「これに注意してください!」と入力したい場合は、太字の場合は、[B] ボタンをクリックしてからテキストの入力を開始し、[B] ボタンをもう一度クリックするまで、入力したすべての文字が太字になります。

これをやってのける方法についてのアイデアはありますか?私は十分に明確であったことを願っています:)

4

5 に答える 5

12

興味のある方のために、ToggleButton が押されたときにカーソル位置 (以下の「styleStart」変数) を保存することでこれを機能させ、ユーザーがさらに文字を入力すると、一致する StyleSpan を removeSpan() で実際に削除してから、再保存された元のカーソル位置 + 現在入力されている文字の長さを使用して、 setSpan() で元に戻します。

また、ユーザーがカーソル位置を変更したかどうかを追跡して、不要なテキストのスタイルを設定しないようにする必要もあります。TextWatcher コードは次のとおりです。

final EditText contentEdit = (EditText) findViewById(R.id.content);
        contentEdit.addTextChangedListener(new TextWatcher() { 
            public void afterTextChanged(Editable s) { 
                //add style as the user types if a toggle button is enabled
                ToggleButton boldButton = (ToggleButton) findViewById(R.id.bold);
                ToggleButton emButton = (ToggleButton) findViewById(R.id.em);
                ToggleButton bquoteButton = (ToggleButton) findViewById(R.id.bquote);
                ToggleButton underlineButton = (ToggleButton) findViewById(R.id.underline);
                ToggleButton strikeButton = (ToggleButton) findViewById(R.id.strike);
                int position = Selection.getSelectionStart(contentEdit.getText());
                if (position < 0){
                    position = 0;
                }

                if (position > 0){

                    if (styleStart > position || position > (cursorLoc + 1)){
                        //user changed cursor location, reset
                        styleStart = position - 1;
                    }

                    cursorLoc = position;

                    if (boldButton.isChecked()){  
                        StyleSpan[] ss = s.getSpans(styleStart, position, StyleSpan.class);

                        for (int i = 0; i < ss.length; i++) {
                            if (ss[i].getStyle() == android.graphics.Typeface.BOLD){
                                s.removeSpan(ss[i]);
                            }
                        }
                        s.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                    if (emButton.isChecked()){
                        StyleSpan[] ss = s.getSpans(styleStart, position, StyleSpan.class);

                        boolean exists = false;
                        for (int i = 0; i < ss.length; i++) {
                            if (ss[i].getStyle() == android.graphics.Typeface.ITALIC){
                                s.removeSpan(ss[i]);
                            }
                        }
                        s.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                    if (bquoteButton.isChecked()){

                        QuoteSpan[] ss = s.getSpans(styleStart, position, QuoteSpan.class);

                        for (int i = 0; i < ss.length; i++) {
                                s.removeSpan(ss[i]);
                        }
                        s.setSpan(new QuoteSpan(), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                    if (underlineButton.isChecked()){
                        UnderlineSpan[] ss = s.getSpans(styleStart, position, UnderlineSpan.class);

                        for (int i = 0; i < ss.length; i++) {
                                s.removeSpan(ss[i]);
                        }
                        s.setSpan(new UnderlineSpan(), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                    if (strikeButton.isChecked()){
                        StrikethroughSpan[] ss = s.getSpans(styleStart, position, StrikethroughSpan.class);

                        for (int i = 0; i < ss.length; i++) {
                                s.removeSpan(ss[i]);
                        }
                        s.setSpan(new StrikethroughSpan(), styleStart, position, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                }
            } 
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
                    //unused
            } 
            public void onTextChanged(CharSequence s, int start, int before, int count) { 
                        //unused
                } 
});

ToggleButton のクリック アクションの 1 つを次に示します。

final ToggleButton boldButton = (ToggleButton) findViewById(R.id.bold);   

            boldButton.setOnClickListener(new Button.OnClickListener() {
                public void onClick(View v) {

                    EditText contentText = (EditText) findViewById(R.id.content);

                    int selectionStart = contentText.getSelectionStart();

                    styleStart = selectionStart;

                    int selectionEnd = contentText.getSelectionEnd();

                    if (selectionStart > selectionEnd){
                        int temp = selectionEnd;
                        selectionEnd = selectionStart;
                        selectionStart = temp;
                    }


                    if (selectionEnd > selectionStart)
                    {
                        Spannable str = contentText.getText();
                        StyleSpan[] ss = str.getSpans(selectionStart, selectionEnd, StyleSpan.class);

                        boolean exists = false;
                        for (int i = 0; i < ss.length; i++) {
                            if (ss[i].getStyle() == android.graphics.Typeface.BOLD){
                                str.removeSpan(ss[i]);
                                exists = true;
                            }
                        }

                        if (!exists){
                            str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }

                        boldButton.setChecked(false);
                    }
                }
        });

もっと良い解決策があるかもしれません。

于 2010-06-23T16:42:27.377 に答える
5

TextWatcherおよびaddTextChangedListener()メソッドを使用して、入力するすべての文字の後にスタイルを更新するだけです。

わかりました、これは必要最小限のサンプル コードです。

int mStart = -1;

// Bold onClickListener
public void onClick(View view)
{
    if(mStart == -1) mStart = mEditText.getText().length();
    else mStart = -1;
}

// TextWatcher
onTextChanged(CharSequence s, int start, int before, int count)
{
    if(mStart > 0)
    {
        int end = mEditText.getText().length();
        mEditText.getText().setSpan(new StyleSpan(android.graphics.Typeface.BOLD), mStart, end - mStart, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}
于 2010-06-22T21:25:22.937 に答える
2

これが古いスレッドであることは知っていますが、同僚がWeb でDroidWriterを見つけました。私はそれで少し遊んでみましたが、それはかなり自明であり、使用と変更が非常に簡単です。これが、リッチ テキスト エディターの作成を検討しているすべての人に役立つことを願っています。

于 2014-09-05T17:17:07.877 に答える
1

android-richtexteditorと呼ばれるオープン ソースの EditText リッチ テキスト エディターがありますが、r5 でコードが不可解に削除されました。コードは古いリビジョンにも残っています。アクセスするには、svn を使用して r4 以前をチェックアウトします。このコードは、斜体、下線、カラー ピッカー、テキスト サイズなどをサポートしているようです。

これらの質問にも回答: 1 , 2

于 2011-12-15T22:20:34.610 に答える
0

それが最善の解決策であるかどうかはわかりませんが、それが頭に浮かび、誰が知っているかはわかりませんが、それがよりエレガントな解決策にあなたを刺激するでしょう:

「ドキュメント」の階層的なスタイル構造とそのすべてのスタイル タグを内部的に追跡し、入力された各文字で最終出力を再構築/置換することを検討できますか? もちろん、カーソル位置も追跡する必要があります。

于 2010-06-23T14:39:37.157 に答える