【问题标题】:How to limit number of lines in Dynamic Android EditText within AlertDialog如何在 AlertDialog 中限制动态 Android EditText 中的行数
【发布时间】:2015-10-02 13:55:42
【问题描述】:

我在 AlertDialog 中动态创建 EditText 并希望限制显示的行数。目前,EditText 会随着每个回车保持垂直扩展。这会导致对话框按钮在某个点之后不可见。我已将代码隔离为以下内容:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button b = (Button) findViewById(R.id.button);
    b.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
            EditText input = new EditText(v.getContext());
            input.setLines(4);
            //input.setMaxLines(4);
            input.setSingleLine(false);
            input.setGravity(Gravity.TOP);
            //input.setVerticalScrollBarEnabled(true);
            builder.setView(input);
            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {     }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {    }
            });
            AlertDialog d = builder.create();
            d.show();
        }
    });

}

}

我很乐意 a) 限制文本行数或 b) 在 X 行之外出现一个滚动条。

我尝试在 EditText 上设置一些属性,包括“setMaxLines”、“setHeight”和“setVerticalScrollBarEnabled”,但这些都不起作用。

我意识到存在一些针对类似问题的现有建议,但没有在动态创建 EditText 并在 AlertDialog 中创建的地方。任何帮助或建议将不胜感激。

【问题讨论】:

  • 看我的回答。希望对你有帮助。

标签: android android-layout


【解决方案1】:

如果您想设置固定行数,您应该这样做

setLines(int numOfLines);

如果您想设置行数限制,将在输入时添加

setMaxLines(int limit);

对于更多信息,您可以使用

限制为最小行数
setMinLines(int limit);

【讨论】:

  • 好的,这实际上是正确的答案,我以为我已经尝试过了,但我没有做对。我的问题是尝试使用“setLines”和“setMaxLines”。为了实现我想要的解决方案,不需要疯狂的代码,我只使用了“setMinLines”和“setMaxLines”,根本没有使用“setLines”。谢谢 4k3R。
  • 既然我的回答解决了你的问题,你应该将此答案标记为正确@OP
【解决方案2】:

您可以限制 LimitedEditText 组件中的行数

您可以限制 LimitedEditText 组件中的字符数

如果您超出文本中间某处的字符或行数限制,光标 不会把你带到最后——它会留在你曾经去过的地方。

我关闭了监听器,因为每次调用 setText() 方法都会递归调用这 3 个回调方法,以防用户超出字符或行数限制。

import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;

/**
* EditText subclass created to enforce limit of the lines number in editable
* text field
*/
public class LimitedEditText extends EditText {

/**
 * Max lines to be present in editable text field
 */
private int maxLines = 1;

/**
 * Max characters to be present in editable text field
 */
private int maxCharacters = 50;

/**
 * application context;
 */
private Context context;

public int getMaxCharacters() {
    return maxCharacters;
}

public void setMaxCharacters(int maxCharacters) {
    this.maxCharacters = maxCharacters;
}

@Override
public int getMaxLines() {
    return maxLines;
}

@Override
public void setMaxLines(int maxLines) {
    this.maxLines = maxLines;
}

public LimitedEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
}

public LimitedEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
}

public LimitedEditText(Context context) {
    super(context);
    this.context = context;
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    TextWatcher watcher = new TextWatcher() {

        private String text;
        private int beforeCursorPosition = 0;

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {                
            //TODO sth
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            text = s.toString();
            beforeCursorPosition = start;
        }

        @Override
        public void afterTextChanged(Editable s) {

            /* turning off listener */
            removeTextChangedListener(this);

            /* handling lines limit exceed */
            if (LimitedEditText.this.getLineCount() > maxLines) {
                LimitedEditText.this.setText(text);
                LimitedEditText.this.setSelection(beforeCursorPosition);
            }

            /* handling character limit exceed */
            if (s.toString().length() > maxCharacters) {
                LimitedEditText.this.setText(text);
                LimitedEditText.this.setSelection(beforeCursorPosition);
                Toast.makeText(context, "text too long", Toast.LENGTH_SHORT)
                        .show();
            }

            /* turning on listener */
            addTextChangedListener(this);

        }
    };

    this.addTextChangedListener(watcher);
}

}

【讨论】:

  • 我对此投了赞成票,因为它与我必须采用完全相同的方法来获得我想要的功能。我想要最大行数,而不是字符是唯一的区别。
【解决方案3】:

与 Darshan 的回答一样,我最终扩展了 EditText,实现了 TextWatcher 接口并查看行数何时超过设置的限制。当它这样做时,保存的光标位置/文本将被恢复。见以下代码:

public class MaxEditText extends EditText implements TextWatcher {

private String saved;
private int positionSaved;
private int maxLines;

public MaxEditText(Context context, int maxLines) {
    super(context);
    this.maxLines = maxLines;
    this.setLines(maxLines);
    this.setSingleLine(false);
    this.setGravity(Gravity.TOP);
    this.addTextChangedListener(this);
}

@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {

}

@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
    saved = arg0.toString();
    positionSaved = ((EditText) this).getSelectionStart();
}

@Override
public void afterTextChanged(Editable arg0) {
    if (this.getLineCount() > maxLines)
    {
        this.setText(saved);
        ((EditText) this).setSelection(positionSaved-1);
    }
}

}

在我看来,必须“撤消”输入的内容而不是首先阻止输入文本,这似乎有点像黑客,所以如果有人有其他选择,请发布。

【讨论】:

  • 原始问题不需要这种方法,只有在您打算以某种方式过滤文本时才有用。
猜你喜欢
  • 2017-07-09
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 2011-07-18
  • 2013-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多