如何在不替换旧文本的情况下向 TextView 添加文本?

Posted

技术标签:

【中文标题】如何在不替换旧文本的情况下向 TextView 添加文本?【英文标题】:How to add text to TextView without replacing the old text? 【发布时间】:2018-10-22 18:46:49 【问题描述】:

正如我在标题中提到的,我想在 Textview 中添加文本而不替换之前的文本。

在我的应用程序中,我有一个 TextView 和 7 个按钮。每次单击按钮时,我都会将按钮的文本设置为 TextView。

如果第一次单击该按钮,则将文本设置为 TextView,如果第二次单击同一个按钮,我将从 TextView 中删除该按钮的文本。

这里我想要做的是 7 个按钮,我想在 TextView 中设置位置(太阳坐的唯一性),当点击相应的按钮时,文本设置为 TextView,如果第二次点击按钮文本的特定位置应删除。

此处的文本不应替换之前重要的文本,如果某些按钮被选中并再次被取消选中,则意味着 TextView 应将默认文本显示为“从不”

我试图从 SO 获取源代码,但找不到明确的解决方案。

如果有人帮助我摆脱困境,那对我很有帮助。

编码

public class CreateAlarm extends Activity implements View.OnClickListener 

    private Button mbtn_Sun, mbtn_Mon, mbtn_Tue, mbtn_Wed, mbtn_Thu, mbtn_Fri, mbtn_Sat;

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

        mRepeat = (TextView) findViewById(R.id.mRepeat);

        mbtn_Sun = (Button) findViewById(R.id.mbtn_Sun);
        mbtn_Mon = (Button) findViewById(R.id.mbtn_Mon);
        mbtn_Tue = (Button) findViewById(R.id.mbtn_Tue);
        mbtn_Wed = (Button) findViewById(R.id.mbtn_Wed);
        mbtn_Thu = (Button) findViewById(R.id.mbtn_Thu);
        mbtn_Fri = (Button) findViewById(R.id.mbtn_Fri);
        mbtn_Sat = (Button) findViewById(R.id.mbtn_Sat);

        mbtn_Sun.setOnClickListener((View.OnClickListener) this);
        mbtn_Mon.setOnClickListener((View.OnClickListener) this);
        mbtn_Tue.setOnClickListener((View.OnClickListener) this);
        mbtn_Wed.setOnClickListener((View.OnClickListener) this);
        mbtn_Thu.setOnClickListener((View.OnClickListener) this);
        mbtn_Fri.setOnClickListener((View.OnClickListener) this);
        mbtn_Sat.setOnClickListener((View.OnClickListener) this);

        int hours = mTimePicker.getCurrentHour();
        mCancel.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                finish();
            
        );

    

    @Override
    public void onClick(View v) 
        switch (v.getId()) 
            case R.id.mbtn_Sun:
                if (mRepeat.getText().toString().contains("Sun")) 
                    mRepeat.setText("");
                 else
                    mRepeat.setText("Sun");
                break;
            case R.id.mbtn_Mon:
                if (mRepeat.getText().toString().contains("Mon")) 
                    mRepeat.setText("");
                 else
                    mRepeat.setText("Mon");
                break;
            case R.id.mbtn_Tue:
                if (mRepeat.getText().toString().contains("Tue")) 
                    mRepeat.setText("");
                 else
                    mRepeat.setText("Tue");
                break;
            case R.id.mbtn_Wed:
                if (mRepeat.getText().toString().contains("Wed")) 
                    mRepeat.setText("");
                 else
                    mRepeat.setText("Wed");
                break;
            case R.id.mbtn_Thu:
                if (mRepeat.getText().toString().contains("Thu")) 
                    mRepeat.setText("");
                 else
                    mRepeat.setText("Thu");
                break;
            case R.id.mbtn_Fri:
                if (mRepeat.getText().toString().contains("Fri")) 
                    mRepeat.setText("");
                 else
                    mRepeat.setText("Fri");
                break;
            case R.id.mbtn_Sat:
                if (mRepeat.getText().toString().contains("Sat")) 
                    mRepeat.setText("");
                 else
                    mRepeat.setText("Sat");
                break;
            default:
                    mRepeat.setText("Never");
        
    

图片:

默认情况下,TextView 文本是“从不”。

【问题讨论】:

【参考方案1】:

您可以将 TreeMap 定义为:

private TreeMap<Integer, String> mAlarmDays = new TreeMap<>();

作为您班级的一个字段,并在单击相应按钮时在 TreeMap 中添加/删除日期。所以onClick方法的实现将是:

@Override
public void onClick(View v) 
    switch (v.getId()) 
        case R.id.mbtn_Sun:
            if (mRepeat.getText().toString().contains("Sun")) 
                mAlarmDays.remove(0);
             else
                mAlarmDays.put(0, "Sun");
            break;
        case R.id.mbtn_Mon:
            if (mRepeat.getText().toString().contains("Mon")) 
                mAlarmDays.remove(1);
             else
                mAlarmDays.put(1, "Mon");
            break;
        case R.id.mbtn_Tue:
            if (mRepeat.getText().toString().contains("Tue")) 
                mAlarmDays.remove(2);
             else
                mAlarmDays.put(2, "Tue");
            break;
        case R.id.mbtn_Wed:
            if (mRepeat.getText().toString().contains("Wed")) 
                mAlarmDays.remove(3);
             else
                mAlarmDays.put(3, "Wed");
            break;
        case R.id.mbtn_Thu:
            if (mRepeat.getText().toString().contains("Thu")) 
                mAlarmDays.remove(4);
             else
                mAlarmDays.put(4, "Thu");
            break;
        case R.id.mbtn_Fri:
            if (mRepeat.getText().toString().contains("Fri")) 
                mAlarmDays.remove(5);
             else
                mAlarmDays.put(5, "Fri");
            break;
        case R.id.mbtn_Sat:
            if (mRepeat.getText().toString().contains("Sat")) 
                mAlarmDays.remove(6);
             else
                mAlarmDays.put(6, "Sat");
            break;
    
    StringBuilder repeatDays = new StringBuilder();
    if (mAlarmDays.size() == 0) 
        repeatDays = new StringBuilder("Never");
     else 
        for (String day:mAlarmDays.values()) 
            repeatDays.append(day).append(" ");
        
    
    mRepeat.setText(repeatDays.toString());

【讨论】:

@Nikson 欢迎 虽然这个解决方案在某些方面比我的要好,但我只是想让它成为最好的。 Mapandroid 中应该避免使用,SparseArray 是作为替代品而诞生的,因为只有在使用 int 作为 key 时才能更好地分配内存。这里提到了利弊***.com/questions/25560629/sparsearray-vs-hashmap。 Android 也建议使用这种方法,因此请考虑使用SparseArray @TamHuynh 我们需要按键对地图进行排序。 是的,我明白,它可以通过索引 0-6 的 for 循环来完成并获取值。再次权衡案例。不过还好,看具体情况和开发者风格,我就是想太多了【参考方案2】:

您应该首先设置每个按钮的 ID,将其添加到每个特定按钮的 xml 中:android:id="sun" 和 ...

【讨论】:

【参考方案3】:

我的建议是:使用单个 TextView 会使你的逻辑相当复杂

改为使用水平的LinearLayout,您将在内部有 7 个TextView,并带有预定义的文本和位置。只需根据单击的按钮显示/隐藏它们,您不必处理任何复杂的字符串分析。

【讨论】:

你不认为这会导致更多的代码需要维护吗?此外,更多的视图会消耗更多的内存。 More code to be maintained:我的直觉说不,您的解决方案目前仅将所有逻辑保留在 1 个字符串中,因此它必须是一个复杂的 if-else 代码:查找、替换、将字符串插入字符串有点痛苦。 more views consume more memory:我的经验说没关系。这是一种权衡情况,性能与内存进行交易,反之亦然。另外我之前要处理一个非常大的活动,有近百个视图和片段,它们仍然处于良好状态。在你的情况下,我假设这是一个设置活动,所以它不是主要活动,完成后一切都会被清除 7-views-with-easy-logic 与 1-view-with-painful-logic 交易对我来说是值得的 当然,如果你喜欢的话,你可以去。我们开发人员有时会有不同的偏好。 :)

以上是关于如何在不替换旧文本的情况下向 TextView 添加文本?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不影响周围文本的情况下向 div 添加文本?

如何在不提交到应用商店的情况下向客户展示 iPhone 应用(临时分发)

SwiftUI - 有没有办法在不覆盖子视图的任何手势的情况下向视图添加手势?

如何在不滚动 textView 的情况下使 UITableViewCell 的高度扩展以适应 UITextView 的内容并包装文本? (斯威夫特 5)

如何在不复制对象的情况下向 Python 公开返回 C++ 对象的函数?

如何在不覆盖的情况下向 Firebase Firestore 添加值?