This question already has answers here:
Implementing a rich text editor in Android?
(7 answers)
Closed 5 years ago.
I am making a Note Making App which has a feature of adding Bold text via a button. When the bold button is clicked the bold mode should be turned on i.e the text taken from user in EditText should now be Bold. On the next Click on the bold button the bold mode should be turned off i.e text taken from the user should now be of Normal type.
I saw this post. Change future text to bold in EditText in Android
But the answer in that post did not work out.
When I first click the button it takes bold input but when I clicked the button again to take Normal text as input it was still taking bold text as input.
Here is the code:
TextArea.java
package com.example.syed.andtexteditor;
import android.content.Context;
import android.graphics.Typeface;
import android.support.v7.widget.AppCompatEditText;
import android.text.Spannable;
import android.text.style.StyleSpan;
import android.util.AttributeSet;
import android.widget.EditText;
public class TextArea extends AppCompatEditText {
public static final int TYPEFACE_NORMAL = 0;
public static final int TYPEFACE_BOLD = 1;
public static final int TYPEFACE_ITALICS = 2;
public static final int TYPEFACE_BOLD_ITALICS = 3;
private int currentTypeface;
private int lastCursorPosition;
private int tId;
public TextArea(Context context) {
super(context);
lastCursorPosition = this.getSelectionStart();
}
public TextArea(Context context, AttributeSet attrs) {
super(context, attrs);
}
public int gettId() {
return tId;
}
public void settId(int tId) {
this.tId = tId;
}
public void changeTypeface(int tfId) {
currentTypeface = tfId;
lastCursorPosition = this.getSelectionStart();
}
#Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
Spannable str = this.getText();
StyleSpan ss;
int endLength = text.toString().length();
switch(currentTypeface) {
case TYPEFACE_NORMAL:
ss = new StyleSpan(Typeface.NORMAL);
break;
case TYPEFACE_BOLD:
ss = new StyleSpan(Typeface.BOLD);
break;
case TYPEFACE_ITALICS:
ss = new StyleSpan(Typeface.ITALIC);
break;
case TYPEFACE_BOLD_ITALICS:
ss = new StyleSpan(Typeface.BOLD_ITALIC);
break;
default:
ss = new StyleSpan(Typeface.NORMAL);
}
str.setSpan(ss, lastCursorPosition, endLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
MainActivity.java:
package com.example.syed.andtexteditor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
public class MainActivity extends AppCompatActivity {
boolean boldClicked=false;
int typefaceStyle = TextArea.TYPEFACE_NORMAL;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button boldButton = (Button)findViewById(R.id.bold_button);
boldButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextArea t = (TextArea) findViewById(R.id.textInput);
if (!boldClicked)
boldClicked = true;
else if (boldClicked)
boldClicked = false;
if (boldClicked) {
typefaceStyle = TextArea.TYPEFACE_BOLD;
t.changeTypeface(typefaceStyle);
}
}
});
}
}
add this line to your layout's Editext
android:textStyle="bold"
Related
I made a simple quiz on Android Studio which contains 3+ questions. How to make the questions become random without duplicated. This app does not use a database. I'm new to programming so I don't know what to do about this
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
TextView totalQuestionsTextView;
TextView questionTextView;
Button ansA,ansB,ansC,ansD;
Button submitBtn;
int score=0;
int totalQuestions = QuestionAnswer.question.length;
int currentQuestionIndex = 0;
String selectedAnswer = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
totalQuestionsTextView = findViewById(R.id.total_questions);
questionTextView = findViewById(R.id.question);
ansA = findViewById(R.id.ans_A);
ansB = findViewById(R.id.ans_B);
ansC = findViewById(R.id.ans_C);
ansD = findViewById(R.id.ans_D);
submitBtn = findViewById(R.id.submbit_btn);
ansA.setOnClickListener(this);
ansB.setOnClickListener(this);
ansC.setOnClickListener(this);
ansD.setOnClickListener(this);
submitBtn.setOnClickListener(this);
totalQuestionsTextView.setText("Total Questions : "+totalQuestions);
loadNewQuestion();
}
#Override
public void onClick(View view) {
ansA.setBackgroundColor(Color.WHITE);
ansB.setBackgroundColor(Color.WHITE);
ansC.setBackgroundColor(Color.WHITE);
ansD.setBackgroundColor(Color.WHITE);
Button clickedButton = (Button) view;
if(clickedButton.getId()==R.id.submbit_btn){
currentQuestionIndex++;
loadNewQuestion();
}else{
//choices button clicked
selectedAnswer = clickedButton.getText().toString();
clickedButton.setBackgroundColor(Color.MAGENTA);
}
}
void loadNewQuestion(){
if(currentQuestionIndex == totalQuestions){
finishQuiz();
return;
}
questionTextView.setText(QuestionAnswer.question[currentQuestionIndex]);
ansA.setText(QuestionAnswer.choices[currentQuestionIndex][0]);
ansB.setText(QuestionAnswer.choices[currentQuestionIndex][1]);
ansC.setText(QuestionAnswer.choices[currentQuestionIndex][2]);
ansD.setText(QuestionAnswer.choices[currentQuestionIndex][3]);
}
void finishQuiz(){
String passStatus = "";
if (score > totalQuestions*0.60){
passStatus = "Passes";
}else{
passStatus = "Failed";
}
new AlertDialog.Builder(this)
.setTitle(passStatus)
.setMessage("Score is "+score+" out of "+ totalQuestions)
.setPositiveButton("Restart",(dialogInterface, i) -> restartQuiz())
.setCancelable(false)
.show();
}
void restartQuiz(){
score = 0;
currentQuestionIndex = 0;
loadNewQuestion();
}
QuestionAnswer.java
import java.util.Arrays; import java.util.List; import java.util.Random;
public class QuestionAnswer {
public static String[] question = {
"Which company own the android?",
"Which one is not the programming language?",
"Where are you watching this video"
};
public static String choices[][] = {
{"Google", "Apple", "Nokia", "Samsung"},
{"Java", "Kotlin", "Notepad", "Python"},
{"Facebook", "Whatsapp", "Instagram", "Youtube"},
};
public static String correctAnswers[] = {
"Google",
"Notepad",
"Youtube"
};
}
how can i add shuffle.collection or random to make my app show random question instead
You need to find out about Random class first in Java. Thereafter, you will create a random number using Random class in onClick function, then set a question's index to your Random number
I have an activity with two variables
int cifracero
and
int cifrauno
I want to pass those variables to a fragment to be shown in some TextViews as the result of the multiplication made in the previous screen...like a "Congratulations, the multiplication was..."
I need to do something like a bundle to pass the variables as arguments of the second screen, in this case a fragment.
And then I have a third variable resultado which is the result of the multiplication of cifracero and cifrauno
This is the activity code
package com.example.aprendelastablasdemultiplicar;
import androidx.activity.ComponentActivity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.ListFragment;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.w3c.dom.Text;
public class quizingresar extends ComponentActivity {
private EditText cifracero;
private EditText cifrauno;
private TextView resultado;
private Button calcular;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quizingresar);
cifracero = (EditText) findViewById(R.id.cifracero);
cifrauno = (EditText) findViewById(R.id.cifrauno);
resultado = (TextView) findViewById(R.id.resultado);
calcular = (Button)findViewById(R.id.calcular);
TextWatcher textWatcher = 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) {
int multiplicationResult = multiplicarValores();
resultado.setText(Integer.toString(multiplicationResult));
}
#Override
public void afterTextChanged(Editable s) {
}
};
cifracero.addTextChangedListener(textWatcher);
cifrauno.addTextChangedListener(textWatcher);
calcular.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openCongratulationsCalcular();
}
});
}
private int multiplicarValores() {
final String strnumber0 = cifracero.getText().toString();
final String strnumber1 = cifrauno.getText().toString();
int number0 = 0;
int number1 = 0;
try {
number0 = Integer.parseInt(strnumber0);
} catch (NumberFormatException e) {
}
try {
number1 = Integer.parseInt(strnumber1);
} catch (NumberFormatException e) {
}
return number0 * number1;
}
public void openCongratulationsCalcular(){
Intent intent = new Intent(this, congratulationscalcular.class);
startActivity(intent);
}
}
I need to recover the variables from the previous screen to be shown in the new fragment screen
You can have both of your fragments share the data between them by having them both under the same viewmodel, as shown here.
If you are going to be swapping screens, I think a very efficient solution would be to pass the desired data from one (screen) fragment to another using attributes in your Navigation Graph. Shown here.
Take a look at Data-Binding as well if you'd like, might be useful.
Intent intent = new Intent(this, DisplayMessageActivity.class);
String result = resultado.getText().toString();
intent.putExtra("EXTRA_MESSAGE", result);
startActivity(intent);
to get the message that was passed by the first activity
Intent intent = getIntent();
String message = intent.getStringExtra("EXTRA_MESSAGE");
I'm tring to build an simple android game.
Users answer the questions, when the answer is correct, it is continue..
I want to add time control for each answer.
I tried to add handler function, but I didn't.
My Code;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class EasyGameActivity extends Activity {
public int score = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_easygame);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
finishScreen();
}
}, 5000);
startGame();
}
private void startGame() {
// TODO Auto-generated method stub
Button b1 = (Button)findViewById(R.id.answer_one);
Button b2 = (Button)findViewById(R.id.answer_two);
Button b3 = (Button)findViewById(R.id.answer_three);
Button b4 = (Button)findViewById(R.id.answer_four);
Random number = new Random();
int first = number.nextInt(100)+1;
int second = number.nextInt(100)+1;
int answer = first + second;
int rnd1 = answer + 1;
int rnd2 = answer + 2;
int rnd3 = answer - 1;
final String a = Integer.toString(answer);
String b = Integer.toString(rnd1);
String c = Integer.toString(rnd2);
String d = Integer.toString(rnd3);
((TextView) findViewById(R.id.display)).setText(Integer.toString(first) + '+' + Integer.toString(second));
List<Button> buttons = Arrays.asList(b1, b2, b3, b4);
List<String> texts = Arrays.asList(a, b, c, d);
Collections.shuffle(texts);
int i = 0;
OnClickListener onClick = new OnClickListener() {
public void onClick(View view) {
Button button = (Button) view;
String value = (String) button.getText();
if(value == a) {
checkTrue();
} else {
finishScreen();
}
}
};
for(Button button : buttons) {
button.setText(texts.get(i++));
button.setOnClickListener(onClick);
}
}
private void checkTrue() {
score++;
((TextView) findViewById(R.id.score)).setText(Integer.toString(score));
startGame();
}
private void finishScreen() {
score = 0;
startActivity (new Intent("com.bsinternet.mathfast.RESTARTGAMESCREEN"));
finish();
}
}
How can I add time control. Thanks.
This bit of code doesn't look right
if(value == a) {
checkTrue();
} else {
finishScreen();
}
You should be using equals() to check for String equality. At the moment you are checking only object equality, which will evaluate to False, and the code will never call checkTrue().
Do this instead:
if(value.equals(a) {
checkTrue();
} else {
finishScreen();
}
I'm making an app in which I'm using Spannble class to create a highlighter mechanism in an EditText, which works fine. Now, I want to store the span position(s) in a SQLiteDatabase, so that I can reload them and have the Spanned Text to show it in a TextView.
Here's my TextView alongwith the highlighter mechanism -
package com.Swap.RR;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.text.Editable;
import android.text.Spannable;
import android.text.TextWatcher;
import android.text.style.BackgroundColorSpan;
import android.view.Menu;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ToggleButton;
public class Add_New_Note extends Activity {
private EditText note;
private int mStart;
private Typeface Roboto_lt;
private int end;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add__new__note);
note = (EditText) findViewById(R.id.notecontent);
ToggleButton highlighter = (ToggleButton) findViewById(R.id.highlightToggle);
Roboto_lt = Typeface.createFromAsset(getAssets(), "Roboto-Light.ttf");
note.setTypeface(Roboto_lt);
mStart = -1;
final TextWatcher highlightWatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
if(mStart > 0)
{
end = note.getText().length();
note.getText().setSpan(new BackgroundColorSpan(getResources().getColor(R.color.highlighter_green)), mStart, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
public void afterTextChanged(Editable s) {
}
};
highlighter.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton button, boolean isChecked) {
if (isChecked == true) {
//start highlighting when the ToggleButton is ON
if(mStart == -1) mStart = note.getText().length();
else mStart = -1;
mStart = note.getText().length();
note.addTextChangedListener(highlightWatcher);
} else {
//stop highlighting when the ToggleButton is OFF
note.removeTextChangedListener(highlightWatcher);
}
}
});
}
public void noteDone(View v) {
String noteContent = note.getText().toString();
Intent i = new Intent("com.Swap.Notes_page");
i.putExtra("NOTE", noteContent);
setResult(RESULT_OK, i);
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_add__new__note, menu);
return true;
}
}
Please help me with some suggestions on how to do it. Thanks!
Your best bet is to use Html.toHtml() to convert the Spannable into HTML. You can then use Html.fromHtml() to convert the HTML back into a Spannable when you query the database later on. You will want to do adequate testing, though, as toHtml() and fromHtml() are not guaranteed to support the same HTML tags.
I want to allow the user to edit just part of a line of text in my Android app. I see a class called the EasyEditSpan but when I stick it into a TextView nothing happens. I tried making the TextView editable but it still doesn't have any effect. If switch to an EditText then the whole line of text is editable which is also incorrect. Here is my code:
#Override
public void onCreate(Bundle savedInstanceState) {
TextView testView = (TextView)findViewById(R.id.text_view);
testView.setText(buildMiddleEditSpannable("Please enter your ", "Name", " here."));
}
public static Spannable buildMiddleEditSpannable(CharSequence beginning, CharSequence middle, CharSequence end) {
int spanMidStart = beginning.length();
int spanMidEnd = spanMidStart + middle.length();
SpannableString span = new SpannableString(new StringBuilder(middle).insert(0, beginning).append(end));
span.setSpan(new EasyEditSpan(), spanMidStart, spanMidEnd, 0);
return span;
}
After looking at the framework code referring to EasyEditSpan (EasyEditSpan, TextView and TextUtils), it become apparent that even though it says in its description:
Provides an easy way to edit a portion of text.
The currently available functionality is limited to just the second part of the description as follow:
The TextView uses this span to allow the user to delete a chuck of text in one click. the text. TextView removes this span as soon as the text is edited, or the cursor moves.
Here's some quick sample code that demonstrates its use:
public class EasyEditSpanActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final EditText editText = new EditText(this);
setContentView(editText);
showToast("Longclick to set EasyEditSpan for the line on cursor");
editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setSingleLine(false);
editText.setText("####\n#######\n###\n######\n####".replace("#", "text "));
editText.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
final Layout layout = editText.getLayout();
final int line = layout.getLineForOffset(editText.getSelectionStart());
final int start = layout.getLineStart(line);
final int end = layout.getLineEnd(line);
editText.getEditableText().setSpan(new EasyEditSpan(), start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
showToast("Edit line to show EasyEdit window");
return true;
}
});
}
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
So unfortunately if you need a way to allow the user to edit just part of a line of text in your app, EasyEditSpan does not seem to help much. It is likely you will need to implement some code utilizing ClickableSpan and probably a custom dialog.
You might be better of using ClickableSpan and popup a dialog to edit the content. However, I tried to implement partially editable textview. This is not complete and may have some rough edges. It uses three spans and overrides onSelectionChanged(int selStart, int selEnd) and onKeyDown(int keyCode, KeyEvent event) methods to disable edits while the target is part1 or part3. Hope it helps.
//activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.sensei.partialedit.EditTextSelectable
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="#dimen/padding_medium"
android:text="#string/hello_world"
android:background="#00000000"
tools:context=".MainActivity" />
</RelativeLayout>
//MainActivity.java
package com.sensei.partialedit;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditTextSelectable testView = (EditTextSelectable) findViewById(R.id.text_view);
testView.setText("Please enter your ", " Name ", " here.");
}
}
//EditTextSelectable.java
package com.sensei.partialedit;
import android.content.Context;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.method.KeyListener;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.EditText;
public class EditTextSelectable extends EditText {
private String part1;
private String part2;
private String part3;
private ForegroundColorSpan span1;
private CharacterStyle span2;
private ForegroundColorSpan span3;
public EditTextSelectable(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setTag(getKeyListener());
}
public EditTextSelectable(Context context, AttributeSet attrs) {
super(context, attrs);
setTag(getKeyListener());
}
public EditTextSelectable(Context context) {
super(context);
setTag(getKeyListener());
}
public void setText(String part1, String part2, String part3) {
setText(buildMiddleEditSpannable(part1, part2, part3));
setSelection(part1.length() + part2.length() - 1);
}
private Spannable buildMiddleEditSpannable(String part1, String part2,
String part3) {
this.part1 = part1;
this.part2 = part2;
this.part3 = part3;
SpannableStringBuilder spannable = new SpannableStringBuilder(part1
+ part2 + part3);
span1 = new ForegroundColorSpan(Color.GRAY);
spannable.setSpan(span1, 0, part1.length() - 1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
span2 = new UnderlineSpan();
spannable.setSpan(span2, part1.length(),
part1.length() + part2.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
span3 = new ForegroundColorSpan(Color.GRAY);
spannable.setSpan(span3, (part1 + part2).length(),
(part1 + part2 + part3).length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
}
#Override
protected void onSelectionChanged(int selStart, int selEnd) {
if (part1 == null)
return;
if (selStart >= getText().getSpanStart(span2)
&& selEnd <= getText().getSpanEnd(span2)) {
setKeyListener((KeyListener) getTag());
setCursorVisible(true);
} else {
setKeyListener(null);
setCursorVisible(false);
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_ENTER) {
// Just ignore the [Enter] key
return true;
}
int selectionStart = getSelectionStart();
int selectionEnd = getSelectionEnd();
Log.d("partialedit", "OnKeyDown:" + selectionStart + ":" + selectionEnd + ":" + getText().getSpanStart(span2) + ":" + getText().getSpanEnd(span2));
if (selectionStart < part1.length() + 1
|| selectionStart >= getText().length() - part3.length()) {
return true;
}
// Handle all other keys in the default way
return super.onKeyDown(keyCode, event);
}
}