Highlighting textview with color like Adobe PDF - android

I'm trying to add menu to focus textview to highlight a word or phrase.
Currently my code has issues
1. highlights more than one word if the word appears more than once
2. Highlighted color disappears on app exit.
TextView textView = (TextView) findViewById(R.id.textView);
textView.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
getMenuInflater().inflate(R.menu.h_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.highlight:
setTextBG();
return true;
default:
break;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});
}
private void setTextBG() {
String selectedText = "";
if (textView.isFocused()) {
final int textStartIndex = textView.getSelectionStart();
final int textEndIndex = textView.getSelectionEnd();
int min = 0;
int max = textView.getText().length();
min = Math.max(0, Math.min(textStartIndex, textEndIndex));
max = Math.max(0, Math.max(textStartIndex, textEndIndex));
selectedText = textView.getText().subSequence(min, max).toString().trim();
}
int txt = textView.getText().toString().indexOf(selectedText, 0);
Spannable mywords = new SpannableString(textView.getText().toString());
for (int i = 0; i < textView.getText().toString().length() && whateva != -1;
i = whateva+1) {
txt = textView.getText().toString().indexOf(selectedText, i);
if (txt == -1) break;
else {
mywords.setSpan(new BackgroundColorSpan(Color.YELLOW), txt, txt+selectedText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(mywords, TextView.BufferType.SPANNABLE);
}
}
Toast.makeText(getApplicationContext(), selectedText, Toast.LENGTH_SHORT).show();
}

Please find below example for highlighting more than one word in content.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TextView textContent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textContent = (TextView) findViewById(R.id.txtContent);
highlightWords();
}
private void highlightWords() {
String content = "This is just a demo of how to highlight more than one word in Android";
textContent.setText(getSpannableWord(content));
}
private Spannable getSpannableWord(String content) {
Spannable spannableString = new SpannableString(content);
// Create list of highlighted word and add to list every time user highlights
ArrayList<HighlightedWord> words = new ArrayList<>();
//1st highlighted word
HighlightedWord highlightedWord1 = new HighlightedWord("demo", 15);
words.add(highlightedWord1);
//2nd highlighted word
HighlightedWord highlightedWord2 = new HighlightedWord("highlight", 30);
words.add(highlightedWord2);
for (HighlightedWord highlightedWord : words) {
spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), highlightedWord.getStartIndex(),
highlightedWord.getStartIndex()+ highlightedWord.getWord().length(), Spannable
.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spannableString;
}
}
Thanks!

Related

Change future text to bold in EditText in Android

I am making a basic text editor app for Android and currently working on formatting the text.
I have an EditText named text_area where the user types his text and a ToggleButton called bold that sets the text to bold. Initially, using the EditText.setTypeface method, all of the text in text_area would change to bold when the button is on. Using the answer provided in this question, I was able to change only the selected text to bold.
What I really want to do though is that when the button is pressed, all the previously typed text (normal and/or bold) remain unchanged, and whatever the user types next is typed in bold.
Here's my code (Could someone also tell me what the code under the else statement does):
bold.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
if(bold.isChecked()==true) {
Spannable str = textarea.getText();
if(textarea.getSelectionEnd() > textarea.getSelectionStart())
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
textarea.getSelectionStart(), textarea.getSelectionEnd(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
else
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
textarea.getSelectionEnd(),
textarea.getSelectionStart(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
});
I was stuck on the same issue, and after hours of trying, this is what I came up with.
First, whenever you check the bold/italics whatever styled checkbox you want to apply, you want to get the current cursor position.
//if bold is checked
YourEditText.getSelectionStart();
YourEditText.getSelectionEnd();
both gives you the current cursor position of the EditText if no text is highlighted.
Store this value into a variable.
int lastCursorPosition = YourEditText.getSelectionStart();
Then, I overrode the onTextChanged function of the EditText. Since we only want to set span from the last cursor position to the end of wherever change is made, we set the span from lastCursorPosition to the end of the text.
int endOfString = YourEditText.getText().toString().length();
StyleSpan ss = new StyleSpan(Typeface.BOLD);
str.setSpan(ss, lastCursorPosition, endOfString, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
While doing this, I ran into another problem. Whenever I applied another span to another part of the text, previous styles disappeared. I fixed this by creating new StyleSpan for each time a new style was applied. Minimal code to understand:
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;
...
#Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
Spannable str = this.getText();
StyleSpan ss;
int endOfString = text.toString().length();
//current typeface is determined by bold, italics, checkboxes, etc
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, endOfString, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
Full TextArea class I've written:
public class TextArea extends EditText {
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);
}
}
From MainActivity.java
TextArea t = new TextArea(context);
int typefaceStyle = TextArea.TYPEFACE_NORMAL;
CheckBox boldCheckbox = (CheckBox) findViewById(R.id.post_bold_checkbox);
boldCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
boldChecked = isChecked;
if(italicsChecked && boldChecked) {
typefaceStyle = TextArea.TYPEFACE_BOLD_ITALICS;
} else if (boldChecked){
typefaceStyle = TextArea.TYPEFACE_BOLD;
} else if (italicsChecked) {
typefaceStyle = TextArea.TYPEFACE_ITALICS;
} else {
typefaceStyle = TextArea.TYPEFACE_NORMAL;
}
t.changeTypeface(typefaceStyle);
}
});
My very first reply on StackOverflow! Hope this helped :-)

Android: Listview Items not Showing

My items for Listview are not showing, can someone point me where is the error.
There is no error when adding items but its not showing on the Listview. I revised my post, I'm trying to use BaseAdapter to populate the items. I can confirm that the items are added to the database because the total amount is updated everytime i add item.
public class ViewTransactions extends Activity {
private ListView mListViewTransactions;
private TransactionAdapter mAdapter;
private List<TransactionModel> mListTransactions;
/** transactions data source. */
private TransactionDao transactionSource;
/** Currently selected broker, as specified by intent received from ViewBrokers class. */
private BrokerModel currentBroker;
/** The sum total of all transactions for the active broker. */
private BigDecimal brokerTotal;
private ArrayAdapter<TransactionModel> aa;
/** Action mode for the context menu. */
private ActionMode aMode;
/** Call back methods for the context menu. */
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
/** Title which displays broker name. */
private TextView title;
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_transactions, menu);
// disable listener here; moved from onPrepareActionMode
title = (TextView) findViewById(R.id.exCat);
title.setClickable(false); // prevent navigation away from activity
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
title = (TextView) findViewById(R.id.exCat);
title.setClickable(false); // prevent navigation away from activity
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
// edit selected expense
editTransaction();
mode.finish(); // Action picked, so close the CAB
return true;
case R.id.action_del:
// delete selected expense
deleteTransaction();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
// unselect item that was selected (if it wasn't deleted)
final ListView lv = (ListView)findViewById(R.id.tList);
lv.clearChoices();
lv.setItemChecked(lv.getCheckedItemPosition(), false);
lv.post(new Runnable() {
#Override
public void run() {
lv.setChoiceMode(ListView.CHOICE_MODE_NONE);
}
});
aMode = null;
title.setClickable(true); // restore broker name click
}
};
/**
* Class to asynchronously retrieve transactions from database.
*/
private class GetTransactions extends AsyncTask<Void, Void, List<TransactionModel>> {
#Override
protected List<TransactionModel> doInBackground(Void... params) {
// retrieve all transactions for the user and broker
return transactionSource.getTransactions(currentBroker);
}
#Override
protected void onPostExecute(final List<TransactionModel> result) {
mAdapter = new TransactionAdapter(ViewTransactions.this, mListTransactions);
mListViewTransactions.setAdapter(mAdapter);
mListViewTransactions.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
// Called when the user long-clicks on an item
public boolean onItemLongClick(AdapterView<?> aView, View view, int i, long l) {
if (aMode != null) {
return false;
}
mListViewTransactions.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// mark item at position i as selected
mListViewTransactions.setItemChecked(i, true);
// Start the CAB using the ActionMode.Callback defined above
aMode = ViewTransactions.this.startActionMode(mActionModeCallback);
return true;
}
});
}
}
/**
* Class to asynchronously add new expense to database.
*/
private class AddTransaction extends AsyncTask<String, Void, TransactionModel> {
#Override
protected TransactionModel doInBackground(String... params) {
return transactionSource.newTransaction(params[0], new BigDecimal(params[1]), params[2],
currentBroker);
}
#Override
protected void onPostExecute(TransactionModel result) {
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
mAdapter = new TransactionAdapter(ViewTransactions.this, mListTransactions);
// mAdapter.add(result);
mAdapter.notifyDataSetChanged();
// update total
brokerTotal = brokerTotal.add(result.getTransactionAmount());
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
}
}
/**
* Class to asynchronously edit an expense in database.
*/
private class EditTransaction extends AsyncTask<TransactionModel, Void, TransactionModel> {
#Override
protected TransactionModel doInBackground(TransactionModel... params) {
return transactionSource.editTransaction(params[0]);
}
#Override
protected void onPostExecute(TransactionModel result) {
// #SuppressWarnings("unchecked")
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
aa.notifyDataSetChanged();
// update total
brokerTotal = brokerTotal.add(result.getTransactionAmount());
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
}
}
/**
* Class to asynchronously delete an expense from database.
*/
private class DeleteTransaction extends AsyncTask<TransactionModel, Void, TransactionModel> {
#Override
protected TransactionModel doInBackground(TransactionModel... params) {
return transactionSource.deleteTransaction(params[0]); // delete selected item from db
}
#Override
protected void onPostExecute(TransactionModel result) {
// #SuppressWarnings("unchecked")
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
aa.remove(result); // remove selected item from adapter
aa.notifyDataSetChanged();
// update total
brokerTotal = brokerTotal.subtract(result.getTransactionAmount());
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
}
}
/**
* Method to record a new expense. Called when Add button in action bar is clicked.
*/
private void addTransaction() {
// build dialog to ask for expense details
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Record Transaction");
builder.setMessage("Please enter transaction details.");
// construct input fields
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
final EditText enterDate = new EditText(this);
final EditText enterCost = new EditText(this);
final EditText enterDesc = new EditText(this);
enterDate.setHint("Date");
enterCost.setHint("Amount");
enterDesc.setHint("Transaction");
enterDate.setInputType(InputType.TYPE_CLASS_DATETIME); // date text
enterDate.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
enterCost.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED); // to accept dollar amount
enterCost.setKeyListener(DigitsKeyListener.getInstance("0123456789.-")); // accept digits
enterDesc.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); // description text
enterDesc.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
ll.addView(enterDate);
ll.addView(enterCost);
ll.addView(enterDesc);
builder.setView(ll);
// add ok and cancel buttons
builder.setPositiveButton(R.string.ok, null);
builder.setNegativeButton(R.string.cancel, null);
// create dialog
final AlertDialog dia = builder.create(); // don't show yet
// set listener to description input field to click OK when done
enterDesc.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set listener to date input field to click OK when done
enterDate.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set input mode to let keyboard appear when dialog is shown
dia.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dia.show();
// override onclick for OK button; must be done after show()ing to retrieve OK button
dia.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// retrieve name entered
String date = enterDate.getText().toString().trim();
String cost = enterCost.getText().toString().trim();
String desc = enterDesc.getText().toString().trim();
// perform checks and add if pass
if (cost.equals("")) { // must not be empty
enterCost.setError("Please enter an amount.");
//} else if (!Pattern.matches("^(\\d{1,10})?(\\.\\d{0,2})?$", cost)) { // must be $$
// enterCost.setError("Please enter a valid amount.");
} else {
// can be added
new AddTransaction().execute(date, cost, desc);
dia.dismiss();
}
}
});
}
/**
* Method to edit selected expense. Called when Edit button is clicked in context menu.
*/
private void editTransaction() {
// retrieve adapter and retrieve selected expense
// ListView lv = getListView();
#SuppressWarnings("unchecked")
// final ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
// final TransactionModel exToEdi = aa.getItem(lv.getCheckedItemPosition()); // get item at checked pos
// build dialog to ask for expense details
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Edit Transaction");
builder.setMessage("Please enter transaction details.");
// construct input fields
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
final EditText enterDate = new EditText(this);
final EditText enterCost = new EditText(this);
final EditText enterDesc = new EditText(this);
// enterDate.setText(exToEdi.getTransactionDate());
// enterCost.setText(exToEdi.getTransactionAmount().toString());
// enterDesc.setText(exToEdi.getTransactionDescription());
enterDate.setInputType(InputType.TYPE_CLASS_DATETIME); // description text
enterDate.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
enterCost.setInputType(InputType.TYPE_CLASS_NUMBER); // to accept dollar amount
enterCost.setKeyListener(DigitsKeyListener.getInstance("0123456789.")); // accept digits
enterDesc.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); // description text
enterDesc.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
ll.addView(enterDate);
ll.addView(enterCost);
ll.addView(enterDesc);
builder.setView(ll);
// add ok and cancel buttons
builder.setPositiveButton(R.string.ok, null);
builder.setNegativeButton(R.string.cancel, null);
// create dialog
final AlertDialog dia = builder.create(); // don't show yet
// set listener to description input field to click OK when done
enterDesc.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set listener to date input field to click OK when done
enterDate.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set input mode to let keyboard appear when dialog is shown
dia.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dia.show();
// override onclick for OK button; must be done after show()ing to retrieve OK button
dia.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// retrieve name entered
String date = enterDate.getText().toString().trim();
String cost = enterCost.getText().toString().trim();
String desc = enterDesc.getText().toString().trim();
// perform checks and add if pass
if (cost.equals("")) { // must not be empty
enterCost.setError("Please enter a dollar amount.");
//} else if (!Pattern.matches("^(\\d{1,10})?(\\.\\d{0,2})?$", cost)) { // must be $$
// enterCost.setError("Please enter a valid dollar amount.");
} else {
// can be changed
// brokerTotal = brokerTotal.subtract(exToEdi.getTransactionAmount());
// exToEdi.setTransactionAmount(new BigDecimal(cost));
// exToEdi.setTransactionDescription(desc);
// exToEdi.setTransactionDate(date);
// new EditTransaction().execute(exToEdi);
dia.dismiss();
}
}
});
}
/**
* Method to delete selected expense. Called when Delete button is clicked in context menu.
*/
private void deleteTransaction() {
// get list view and list adapter
// ListView lv = getListView();
// #SuppressWarnings("unchecked")
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
// int pos = lv.getCheckedItemPosition(); // get pos of selected item
// TransactionModel del = aa.getItem(pos); // get item in adapter at position pos
// new DeleteTransaction().execute(del); // delete expense async and update total
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.capital_activity_view_transactions);
initViews();
currentBroker = (BrokerModel) getIntent().getSerializableExtra(IntentTags.CURRENT_BROKER);
// set totalCost = ; here
// set title to broker
TextView title = (TextView) findViewById(R.id.exCat);
title.setText(currentBroker.getBroker());
title.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent it = new Intent(ViewTransactions.this, ViewBrokers.class);
startActivity(it);
}
});
// open data source
transactionSource = new TransactionDao(this);
transactionSource.open();
// display total for user, cat, month/year
brokerTotal = transactionSource.getTotalCost(currentBroker);
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
new GetTransactions().execute(); // retrieve display transactions for the broker
}
private void initViews(){
this.mListViewTransactions = (ListView)findViewById(R.id.tList);
}
#Override
protected void onResume() {
transactionSource.open();
super.onResume();
}
#Override
protected void onPause() {
transactionSource.close();
super.onPause();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu
getMenuInflater().inflate(R.menu.view_transactions, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_new) {
addTransaction();
return true;
} else if (id == R.id.switch_user) {
// Intent intent = new Intent(this, ViewUsers.class);
// startActivity(intent); // start user activity
return true;
}
return super.onOptionsItemSelected(item);
}
}
public class TransactionAdapter extends BaseAdapter {
public static final String TAG = "ListTransactionsAdapter";
private List<TransactionModel> mItems;
private LayoutInflater mInflater;
public TransactionAdapter(Context context, List<TransactionModel> listBrokers) {
this.setItems(listBrokers);
this.mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return (getItems() != null && !getItems().isEmpty()) ? getItems().size() : 0 ;
}
#Override
public TransactionModel getItem(int position) {
return (getItems() != null && !getItems().isEmpty()) ? getItems().get(position) : null ;
}
#Override
public long getItemId(int position) {
return (getItems() != null && !getItems().isEmpty()) ? getItems().get(position).getId() : position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if(v == null) {
v = mInflater.inflate(R.layout.capital_row_layout_transaction, parent, false);
holder = new ViewHolder();
holder.txtCapitalTransactionDate = (TextView) v.findViewById(R.id.capital_broker_date_transaction);
holder.txtCapitalTransaction = (TextView) v.findViewById(R.id.capital_broker_add_transaction);
holder.txtCapitalTransactionAmount = (TextView) v.findViewById(R.id.capital_broker_add_amount);
v.setTag(holder);
}
else {
holder = (ViewHolder) v.getTag();
}
// fill row data
TransactionModel currentItem = getItem(position);
if(currentItem != null) {
holder.txtCapitalTransactionDate.setText(currentItem.getTransactionDate());
holder.txtCapitalTransaction.setText(String.valueOf(currentItem.getTransactionDescription()));
holder.txtCapitalTransactionAmount.setText(String.valueOf(currentItem.getTransactionAmount()));
}
return v;
}
public List<TransactionModel> getItems() {
return mItems;
}
public void setItems(List<TransactionModel> mItems) {
this.mItems = mItems;
}
class ViewHolder {
TextView txtCapitalTransactionDate;
TextView txtCapitalTransaction;
TextView txtCapitalTransactionAmount;
}
}

Using LinkMovementMethod and Native copy/paste in Textview - Android

I have a TextView with html text and I need native copy/paste and clickable links.
I have used the next code, but when I use
setMovementMethod(LinkMovementMethod.getInstance());
the native copy/paste stops to work.
If I change setMovementMethod(LinkMovementMethod.getInstance())
to ArrowKeyMovementMethod, the copy/paste works but the click links stops to work.
I donĀ“t posted all code but setMovementMethod is used in updateDetail method.
Does someome can help me?
Regards, Luiz
My code is:
textDetail = (TextView) view.findViewById(R.id.text_detail);
textDetail.setTextIsSelectable(true);
textDetail.setCustomSelectionActionModeCallback(new ActionMode.Callback()
{
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
}
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// TODO Auto-generated method stub
return false;
}
});
protected void makeLinkClickable(SpannableStringBuilder strBuilder,
final URLSpan span) {
int start = strBuilder.getSpanStart(span);
int end = strBuilder.getSpanEnd(span);
int flags = strBuilder.getSpanFlags(span);
ClickableSpan clickable = new ClickableSpan() {
#Override
public void onClick(View view) {
}
////////
else {
///////////////
}
}
};
strBuilder.setSpan(clickable, start, end, flags);
strBuilder.removeSpan(span);
}
protected void setTextViewHTML(TextView text, String html) {
CharSequence sequence = Html.fromHtml(html);
SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);
URLSpan[] urls = strBuilder.getSpans(0, sequence.length(),
URLSpan.class);
for (URLSpan span : urls) {
makeLinkClickable(strBuilder, span);
}
text.setText(strBuilder);
}
public void updateDetail(String msg) {
setTextViewHTML(textDetail, msg);
textDetail.setMovementMethod(LinkMovementMethod.getInstance());
}

How do I make my ArrayList<ColorSaver> persistent in android?

I have the ArrayList...
ArrayList<ColorSaver> tempList = new ArrayList<ColorSaver>();
and I want it so that when the user closes the app or leaves the app, all the ColorSaver objects in the ArrayList will be there when the user reopens the app. I would prefer to use the SharedPreferences but I can't do that because the list is a custom object...
I have looked around and found out that I can do a serializable but I tried that and failed horribly, so if somebody could guide me through the serializable deal that would be great. Oh and where do I put the code, like in onCreate() in my mainActivity or in the activity that is displaying the ArrayList
My mainActivity class
public class MainActivity extends Activity {
ArrayList<ColorSaver> tempList = new ArrayList<ColorSaver>();
private static final String TAG = "Main Activity";
public static final String PREFS_NAME = "MyPrefsFile";
final Intent intent = new Intent();
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
final NumberPicker rednp = (NumberPicker) findViewById(R.id.redNumberPicker1);
final NumberPicker bluenp = (NumberPicker) findViewById(R.id.blueNumberPicker);
final NumberPicker greennp = (NumberPicker) findViewById(R.id.greenNumberPicker);
switch(item.getItemId())
{
case R.id.save:
Log.i(TAG, "Save item clicked!");
Intent intent = new Intent(this, SaveActivity.class);
intent.putExtra("RedValue", rednp.getValue());
intent.putExtra("BlueValue", bluenp.getValue());
intent.putExtra("GreenValue", greennp.getValue());
intent.putExtra("temparray", tempList);
startActivity(intent);
return true;
case R.id.recall:
Log.i(TAG, "Recall item clicked!");
Intent intent2 = new Intent(this, RecallActivity.class);
intent2.putExtra("temparray", tempList);
startActivity(intent2);
return true;
default:
return super.onOptionsItemSelected(item);
}//End Switch
}
#SuppressWarnings("unchecked")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//ArrayList<ColorSaver> tempList = new ArrayList<ColorSaver>();
Bundle extras = getIntent().getExtras();
final SurfaceView sView = (SurfaceView) findViewById(R.id.surfaceView1);
final NumberPicker np = (NumberPicker) findViewById(R.id.redNumberPicker1);
np.setMaxValue(255);
np.setMinValue(0);
final NumberPicker np2 = (NumberPicker) findViewById(R.id.greenNumberPicker);
np2.setMaxValue(255);
np2.setMinValue(0);
final NumberPicker np3 = (NumberPicker) findViewById(R.id.blueNumberPicker);
np3.setMaxValue(255);
np3.setMinValue(0);
if( extras != null )
{
np.setValue(extras.getInt("savedRValue"));
//np.setValue(intent.getIntExtra("savedRValue", 255));
np2.setValue(extras.getInt("savedGValue"));
//np2.setValue(intent.getIntExtra("savedGValue", 255));
np3.setValue(extras.getInt("savedBValue"));
//np3.setValue(intent.getIntExtra("savedBValue", 255));
tempList = (ArrayList<ColorSaver>) extras.getSerializable("array");
sView.setBackgroundColor(Color.argb(255, np.getValue(), np2.getValue(), np3.getValue()));
}
else
{
Log.i(TAG, "I just don't get it...WTF");
}
np.setOnValueChangedListener( new NumberPicker.
OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal)
{
int rednum, greennum, bluenum;
rednum = np.getValue();
greennum = np2.getValue();
bluenum = np3.getValue();
sView.setBackgroundColor(Color.argb(255, rednum, greennum, bluenum));
}
});
//GREEN NUMBERPICKER LISTENER
np2.setOnValueChangedListener( new NumberPicker.
OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal)
{
int rednum, greennum, bluenum;
rednum = np.getValue();
greennum = np2.getValue();
bluenum = np3.getValue();
sView.setBackgroundColor(Color.argb(255, rednum, greennum, bluenum));
}
});
np3.setOnValueChangedListener( new NumberPicker.
OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal)
{
int rednum, greennum, bluenum;
rednum = np.getValue();
greennum = np2.getValue();
bluenum = np3.getValue();
sView.setBackgroundColor(Color.argb(255, rednum, greennum, bluenum));
}
});
}//End onCreate()
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}//END onCreateOptionsMenu()
}//END CLASS
My saveActivity, where the user saves their color combo to the ArrayList...
public class SaveActivity extends Activity implements Serializable {
private static final String TAG = "Save Activity";
public ArrayList<ColorSaver> savedColors = new ArrayList<ColorSaver>();
#SuppressWarnings("unchecked")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save);
// Show the Up button in the action bar.
setupActionBar();
Bundle extras = getIntent().getExtras();
final Intent intent1 = new Intent(this, MainActivity.class);
Button saveButton = (Button) findViewById(R.id.saveButton1);
final EditText nameField = (EditText) findViewById(R.id.colorNameField);
//final Intent intent = new Intent();
savedColors = (ArrayList<ColorSaver>) extras.getSerializable("temparray");
//Making sure the savedColors arrayList has something in it.
if( savedColors.isEmpty() )
{
ColorSaver temp = new ColorSaver("Rockies Purple", 180, 80, 255);
savedColors.add(temp);
}
saveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
Bundle extras = getIntent().getExtras();
int redcolor, greencolor, bluecolor;
redcolor = extras.getInt("RedValue");
greencolor = extras.getInt("GreenValue");
bluecolor = extras.getInt("BlueValue");
String colorName = nameField.getText().toString();
//Build the new color and add it to the arrayList
ColorSaver saver = new ColorSaver(colorName, redcolor, greencolor, bluecolor);
savedColors.add(saver);
intent1.putExtra("array", savedColors);
Log.i(TAG, savedColors.get(savedColors.size()-1).getColorName());
startActivity(intent1);
}
});
}//END OnCreate()
/**
* Set up the {#link android.app.ActionBar}.
*/
private void setupActionBar() {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.save, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}//END CLASS
My recallActivity where the user recalls their color combos...
public class RecallActivity extends SaveActivity {
private static final String TAG = "Recall Activity";
ArrayList<ColorSaver> colorsArray = new ArrayList<ColorSaver>();
SaveActivity sActivity = new SaveActivity();
#SuppressWarnings("unchecked")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recall);
// Show the Up button in the action bar.
setupActionBar();
final Intent intent1 = new Intent(this, MainActivity.class);
final Spinner colorList = (Spinner) findViewById(R.id.colorsSpinner);
Button grabButton = (Button) findViewById(R.id.grabButton);
Bundle extras = getIntent().getExtras();
colorsArray = (ArrayList<ColorSaver>) extras.getSerializable("temparray");
//Load the spinner with the saved colors
addColorNames(colorsArray);
grabButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
ColorSaver selectedItem = (ColorSaver) colorList.getSelectedItem();
int redValue, greenValue, blueValue;
String name;
redValue = selectedItem.getRedValue();
greenValue = selectedItem.getGreenValue();
blueValue = selectedItem.getBlueValue();
name = selectedItem.getColorName();
intent1.putExtra("savedRValue", redValue);
intent1.putExtra("savedGValue", greenValue);
intent1.putExtra("savedBValue", blueValue);
intent1.putExtra("savedName", name);
intent1.putExtra("array", colorsArray);
startActivity(intent1);
}//END onClick
});
}
/**
* Set up the {#link android.app.ActionBar}.
*/
private void setupActionBar() {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.recall, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}// END onOptionsItemSelected(MenuItem item)
public void addColorNames(ArrayList<ColorSaver> colorsArray1)
{
colorsArray = colorsArray1;
//if( !colorsArray.isEmpty() )
//{
Spinner colorsSpinner = (Spinner) findViewById(R.id.colorsSpinner);
ArrayAdapter<ColorSaver> dataAdapter
= new ArrayAdapter<ColorSaver>
(RecallActivity.this, android.R.layout.simple_spinner_item, colorsArray);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
colorsSpinner.setAdapter(dataAdapter);
Log.i(TAG, savedColors.get(savedColors.size() - 1).toString());
//}
//else
//{
// Log.i(TAG, "colorsSpinner came out to be null....WTF???");
//}
}//End addColorNames()
}//END CLASS
I am greatful of any help!
Take a look at Android's Parcelable implementation.
So, I'm just guessing on your ColorSaver class since it wasn't posted, but you would implement it the following way:
ColorSaver.java
public class ColorSaver implements Parcelable {
private String mName;
private int mRed;
private int mGreen;
private int mBlue;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(mName);
out.writeInt(mRed);
out.writeInt(mGreen);
out.writeInt(mBlue);
}
public static final Parcelable.Creator<ColorSaver> CREATOR
= new Parcelable.Creator<ColorSaver>() {
public ColorSaver createFromParcel(Parcel in) {
return new ColorSaver(in);
}
public ColorSaver[] newArray(int size) {
return new ColorSaver[size];
}
};
private ColorSaver(Parcel in) {
mName = in.readString();
mRed = in.readInt();
mGreen = in.readInt();
mBlue = in.readInt();
}
}
MyActivity.java
public class MyActivity extends Activity {
private static final String COLOR_SAVER_LIST = "com.example.android.ColorSaverList";
private List<ColorSaver> colorSaverList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null && savedInstanceState.containsKey(COLOR_SAVER_LIST)) {
colorSaverList = new ArrayList<ColorSaver>();
colorSaverList = savedInstanceState.getParcelableArrayList(COLOR_SAVER_LIST);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(COLOR_SAVER_LIST, colorSaverList);
}
}

TextView won't clear for some Reason, Android

I hope this isn't a stupid question. I'm having some trouble clearing a TextView. I've looked around and everyone keeps saying use: textView.setText(""); in onCreate but doesn't seem to work for some reason. Basically, my app just accepts a number from an editText then runs the Fibonacci sequence (when a button is clicked) and displays the result in a textView. Well, the sequence displays fine but I want the textview to clear every time I click the button - so far it just keeps adding more text to what's already there.
Am I placing textView.setText(""); in the wrong location? Or am I just missing some other concept? (I also tried placing it from my OnClick - that didn't work either).
Here is my code:
public class MainActivity extends Activity {
// primary widgets
private EditText editText;
private TextView textView;
private Button button1;
static ArrayList<Integer> fibList = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText1);
textView = (TextView) findViewById(R.id.textView2);
button1 = (Button) findViewById(R.id.button1);
//Attempt to clear TextView
textView.setText("");
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String input = editText.getText().toString();
int number = Integer.parseInt(input);
int tmp = 0;
// confirm input
if (number < 20) {
Toast.makeText(getApplicationContext(),
"You entered: " + number, Toast.LENGTH_LONG).show();
for (int i = 0; i <= number; i++) {
fibList.add(fib(i));
// sum even numbers
if (fib(i) % 2 == 0) {
tmp += fib(i);
}
}
} else {
Toast.makeText(getApplicationContext(),
"Number is too Large: " + number, Toast.LENGTH_LONG)
.show();
}
String array = fibList.toString();
textView.setText(array);
}
});
}
// run fibonacci sequence
public static int fib(int n) {
if (n < 2) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
If you want the TextView to clear on each button click then the .setText must go in you onClick. The reason you would put the .setText in your onCreate is to clear the text as soon as your activity is created, but you do not have anything to clear just yet since your button has not yet been pushed so setText will do nothing. Also, since your onCreate will only run once for your activity, it will never go back to the setText again. Try the following:
public class MainActivity extends Activity {
// primary widgets
private EditText editText;
private TextView textView;
private Button button1;
static ArrayList<Integer> fibList = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText1);
textView = (TextView) findViewById(R.id.textView2);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textView.setText(""); //Clear the TextView
fibList.clear(); //Clear your array list before adding new elements
String input = editText.getText().toString();
int number = Integer.parseInt(input);
int tmp = 0;
// confirm input
if (number < 20) {
Toast.makeText(getApplicationContext(),
"You entered: " + number, Toast.LENGTH_LONG).show();
for (int i = 0; i <= number; i++) {
fibList.add(fib(i));
// sum even numbers
if (fib(i) % 2 == 0) {
tmp += fib(i);
}
}
} else {
Toast.makeText(getApplicationContext(),
"Number is too Large: " + number, Toast.LENGTH_LONG)
.show();
}
String array = fibList.toString();
textView.setText(array);
}
});
}
// run fibonacci sequence
public static int fib(int n) {
if (n < 2) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
you will need to clear textView on Button click event before adding new results to it.do it as:
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
textView.setText(""); //<<<<<< clear TextView on Button Click
.....
The problem is more likely in fibList that is not being cleared

Categories

Resources