termux-app

Форк
0
278 строк · 10.2 Кб
1
package com.termux.shared.activities;
2

3
import android.annotation.SuppressLint;
4
import android.app.Activity;
5
import android.content.Context;
6
import android.content.Intent;
7
import android.graphics.Typeface;
8
import android.os.Bundle;
9
import android.text.Editable;
10
import android.text.InputFilter;
11
import android.text.TextWatcher;
12
import android.view.Menu;
13
import android.view.MenuInflater;
14
import android.view.MenuItem;
15
import android.view.View;
16
import android.view.ViewGroup;
17
import android.widget.EditText;
18
import android.widget.HorizontalScrollView;
19
import android.widget.LinearLayout;
20
import android.widget.TextView;
21

22
import androidx.annotation.NonNull;
23
import androidx.appcompat.app.ActionBar;
24
import androidx.appcompat.app.AppCompatActivity;
25
import androidx.appcompat.widget.Toolbar;
26

27
import com.termux.shared.interact.ShareUtils;
28
import com.termux.shared.logger.Logger;
29
import com.termux.shared.R;
30
import com.termux.shared.models.TextIOInfo;
31
import com.termux.shared.view.KeyboardUtils;
32

33
import org.jetbrains.annotations.NotNull;
34

35
import java.util.Locale;
36

37
/**
38
 * An activity to edit or view text based on config passed as {@link TextIOInfo}.
39
 *
40
 * Add Following to `AndroidManifest.xml` to use in an app:
41
 *
42
 * {@code ` <activity android:name="com.termux.shared.activities.TextIOActivity" android:theme="@style/Theme.AppCompat.TermuxTextIOActivity" />` }
43
 */
44
public class TextIOActivity extends AppCompatActivity {
45

46
    private static final String CLASS_NAME = ReportActivity.class.getCanonicalName();
47
    public static final String EXTRA_TEXT_IO_INFO_OBJECT = CLASS_NAME + ".EXTRA_TEXT_IO_INFO_OBJECT";
48

49
    private TextView mTextIOLabel;
50
    private View mTextIOLabelSeparator;
51
    private EditText mTextIOText;
52
    private HorizontalScrollView mTextIOHorizontalScrollView;
53
    private LinearLayout mTextIOTextLinearLayout;
54
    private TextView mTextIOTextCharacterUsage;
55

56
    private TextIOInfo mTextIOInfo;
57
    private Bundle mBundle;
58

59
    private static final String LOG_TAG = "TextIOActivity";
60

61
    @Override
62
    protected void onCreate(Bundle savedInstanceState) {
63
        super.onCreate(savedInstanceState);
64
        Logger.logVerbose(LOG_TAG, "onCreate");
65

66
        setContentView(R.layout.activity_text_io);
67

68
        mTextIOLabel = findViewById(R.id.text_io_label);
69
        mTextIOLabelSeparator = findViewById(R.id.text_io_label_separator);
70
        mTextIOText = findViewById(R.id.text_io_text);
71
        mTextIOHorizontalScrollView = findViewById(R.id.text_io_horizontal_scroll_view);
72
        mTextIOTextLinearLayout = findViewById(R.id.text_io_text_linear_layout);
73
        mTextIOTextCharacterUsage = findViewById(R.id.text_io_text_character_usage);
74

75
        Toolbar toolbar = findViewById(R.id.toolbar);
76
        if (toolbar != null) {
77
            setSupportActionBar(toolbar);
78
        }
79

80
        mBundle = null;
81
        Intent intent = getIntent();
82
        if (intent != null)
83
            mBundle = intent.getExtras();
84
        else if (savedInstanceState != null)
85
            mBundle = savedInstanceState;
86

87
        updateUI();
88
    }
89

90
    @Override
91
    protected void onNewIntent(Intent intent) {
92
        super.onNewIntent(intent);
93
        Logger.logVerbose(LOG_TAG, "onNewIntent");
94

95
        // Views must be re-created since different configs for isEditingTextDisabled() and
96
        // isHorizontallyScrollable() will not work or at least reliably
97
        finish();
98
        startActivity(intent);
99
    }
100

101
    @SuppressLint("ClickableViewAccessibility")
102
    private void updateUI() {
103
        if (mBundle == null) {
104
            finish(); return;
105
        }
106

107
        mTextIOInfo = (TextIOInfo) mBundle.getSerializable(EXTRA_TEXT_IO_INFO_OBJECT);
108
        if (mTextIOInfo == null) {
109
            finish(); return;
110
        }
111

112
        final ActionBar actionBar = getSupportActionBar();
113
        if (actionBar != null) {
114
            if (mTextIOInfo.getTitle() != null)
115
                actionBar.setTitle(mTextIOInfo.getTitle());
116
            else
117
                actionBar.setTitle("Text Input");
118

119
            if (mTextIOInfo.shouldShowBackButtonInActionBar()) {
120
                actionBar.setDisplayHomeAsUpEnabled(true);
121
                actionBar.setDisplayShowHomeEnabled(true);
122
            }
123
        }
124

125
        mTextIOLabel.setVisibility(View.GONE);
126
        mTextIOLabelSeparator.setVisibility(View.GONE);
127
        if (mTextIOInfo.isLabelEnabled()) {
128
            mTextIOLabel.setVisibility(View.VISIBLE);
129
            mTextIOLabelSeparator.setVisibility(View.VISIBLE);
130
            mTextIOLabel.setText(mTextIOInfo.getLabel());
131
            mTextIOLabel.setFilters(new InputFilter[] { new InputFilter.LengthFilter(TextIOInfo.LABEL_SIZE_LIMIT_IN_BYTES) });
132
            mTextIOLabel.setTextSize(mTextIOInfo.getLabelSize());
133
            mTextIOLabel.setTextColor(mTextIOInfo.getLabelColor());
134
            mTextIOLabel.setTypeface(Typeface.create(mTextIOInfo.getLabelTypeFaceFamily(), mTextIOInfo.getLabelTypeFaceStyle()));
135
        }
136

137

138
        if (mTextIOInfo.isHorizontallyScrollable()) {
139
            mTextIOHorizontalScrollView.setEnabled(true);
140
            mTextIOText.setHorizontallyScrolling(true);
141
        } else {
142
            // Remove mTextIOHorizontalScrollView and add mTextIOText in its place
143
            ViewGroup parent = (ViewGroup) mTextIOHorizontalScrollView.getParent();
144
            if (parent != null && parent.indexOfChild(mTextIOText) < 0) {
145
                ViewGroup.LayoutParams params = mTextIOHorizontalScrollView.getLayoutParams();
146
                int index = parent.indexOfChild(mTextIOHorizontalScrollView);
147
                mTextIOTextLinearLayout.removeAllViews();
148
                mTextIOHorizontalScrollView.removeAllViews();
149
                parent.removeView(mTextIOHorizontalScrollView);
150
                parent.addView(mTextIOText, index, params);
151
                mTextIOText.setHorizontallyScrolling(false);
152
            }
153
        }
154

155
        mTextIOText.setText(mTextIOInfo.getText());
156
        mTextIOText.setFilters(new InputFilter[] { new InputFilter.LengthFilter(mTextIOInfo.getTextLengthLimit()) });
157
        mTextIOText.setTextSize(mTextIOInfo.getTextSize());
158
        mTextIOText.setTextColor(mTextIOInfo.getTextColor());
159
        mTextIOText.setTypeface(Typeface.create(mTextIOInfo.getTextTypeFaceFamily(), mTextIOInfo.getTextTypeFaceStyle()));
160

161
        // setTextIsSelectable must be called after changing KeyListener to regain focusability and selectivity
162
        if (mTextIOInfo.isEditingTextDisabled()) {
163
            mTextIOText.setCursorVisible(false);
164
            mTextIOText.setKeyListener(null);
165
            mTextIOText.setTextIsSelectable(true);
166
        }
167

168
        if (mTextIOInfo.shouldShowTextCharacterUsage()) {
169
            mTextIOTextCharacterUsage.setVisibility(View.VISIBLE);
170
            updateTextIOTextCharacterUsage(mTextIOInfo.getText());
171

172
            mTextIOText.addTextChangedListener(new TextWatcher() {
173
                @Override
174
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
175
                @Override
176
                public void onTextChanged(CharSequence s, int start, int before, int count) {}
177
                @Override
178
                public void afterTextChanged(Editable editable) {
179
                    if (editable != null)
180
                        updateTextIOTextCharacterUsage(editable.toString());
181
                }
182
            });
183
        } else {
184
            mTextIOTextCharacterUsage.setVisibility(View.GONE);
185
            mTextIOText.addTextChangedListener(null);
186
        }
187
    }
188

189
    private void updateTextIOInfoText() {
190
        if (mTextIOText != null)
191
            mTextIOInfo.setText(mTextIOText.getText().toString());
192
    }
193

194
    private void updateTextIOTextCharacterUsage(String text) {
195
        if (text == null) text = "";
196
        if (mTextIOTextCharacterUsage != null)
197
            mTextIOTextCharacterUsage.setText(String.format(Locale.getDefault(), "%1$d/%2$d", text.length(), mTextIOInfo.getTextLengthLimit()));
198
    }
199

200
    @Override
201
    public void onSaveInstanceState(@NonNull Bundle outState) {
202
        super.onSaveInstanceState(outState);
203

204
        updateTextIOInfoText();
205
        outState.putSerializable(EXTRA_TEXT_IO_INFO_OBJECT, mTextIOInfo);
206
    }
207

208
    @Override
209
    public boolean onCreateOptionsMenu(final Menu menu) {
210
        final MenuInflater inflater = getMenuInflater();
211
        inflater.inflate(R.menu.menu_text_io, menu);
212
        return true;
213
    }
214

215
    @Override
216
    public boolean onOptionsItemSelected(final MenuItem item) {
217
        String text = "";
218
        if (mTextIOText != null)
219
            text = mTextIOText.getText().toString();
220

221
        int id = item.getItemId();
222
        if (id == android.R.id.home) {
223
            confirm();
224
        } if (id == R.id.menu_item_cancel) {
225
            cancel();
226
        } else if (id == R.id.menu_item_share_text) {
227
            ShareUtils.shareText(this, mTextIOInfo.getTitle(), text);
228
        } else if (id == R.id.menu_item_copy_text) {
229
            ShareUtils.copyTextToClipboard(this, text, null);
230
        }
231

232
        return false;
233
    }
234

235
    @Override
236
    public void onBackPressed() {
237
        confirm();
238
    }
239

240
    /** Confirm current text and send it back to calling {@link Activity}. */
241
    private void confirm() {
242
        updateTextIOInfoText();
243
        KeyboardUtils.hideSoftKeyboard(this, mTextIOText);
244
        setResult(Activity.RESULT_OK, getResultIntent());
245
        finish();
246
    }
247

248
    /** Cancel current text and notify calling {@link Activity}. */
249
    private void cancel() {
250
        KeyboardUtils.hideSoftKeyboard(this, mTextIOText);
251
        setResult(Activity.RESULT_CANCELED, getResultIntent());
252
        finish();
253
    }
254

255
    @NotNull
256
    private Intent getResultIntent() {
257
        Intent intent = new Intent();
258
        Bundle bundle = new Bundle();
259
        bundle.putSerializable(EXTRA_TEXT_IO_INFO_OBJECT, mTextIOInfo);
260
        intent.putExtras(bundle);
261
        return intent;
262
    }
263

264
    /**
265
     * Get the {@link Intent} that can be used to start the {@link TextIOActivity}.
266
     *
267
     * @param context The {@link Context} for operations.
268
     * @param textIOInfo The {@link TextIOInfo} containing info for the edit text.
269
     */
270
    public static Intent newInstance(@NonNull final Context context, @NonNull final TextIOInfo textIOInfo) {
271
        Intent intent = new Intent(context, TextIOActivity.class);
272
        Bundle bundle = new Bundle();
273
        bundle.putSerializable(EXTRA_TEXT_IO_INFO_OBJECT, textIOInfo);
274
        intent.putExtras(bundle);
275
        return intent;
276
    }
277

278
}
279

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.