嗨,伙计们!我正在使用外部sqlite数据库的应用程序。我使用的是示例源代码,我想从一些粗体或斜体样式或不同颜色的条目中摘录。
例如,如果我有这样的条目:黑色是我最喜欢的颜色。我希望我的字符串能识别HTML标签。单词" black"在我的例子中应该是粗体。
我是新手,我需要一些细节方面的帮助。这是我的代码:
WordView.java
public class WordView extends TextView implements OnTouchListener {
private PopupView popup;
private String infoWord;
private ScrollView parent;
private boolean mClickEnabled;
private Typeface transTypeFace, transTypeFaceBold;
private static final Map<String, String[]> FONTS = new HashMap<String, String[]>();
static {
FONTS.put("sans", new String[] { "DejaVuSansCondensed.ttf", "DejaVuSansCondensed-Bold.ttf"});
FONTS.put("serif", new String[] { "DejaVuSerifCondensed.ttf", "DejaVuSerifCondensed-Bold.ttf"});
}
private class Type1Span extends ClickableSpan {
String word;
public Type1Span(String word) {
this.word = word;
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(touchedInstance == this);
ds.setTypeface(transTypeFace);
}
@Override
public void onClick(View widget) {
if (mClickEnabled) {
Uri uri = Uri.parse("ecidiomas://" + word);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addCategory(Intent.CATEGORY_DEFAULT);
widget.getContext().startActivity(intent);
}
}
};
private class Type2Span extends Type1Span {
public Type2Span(String word) {
super(word);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setTypeface(transTypeFaceBold);
}
}
private class TranscriptionTypeSpan extends ForegroundColorSpan {
public TranscriptionTypeSpan(int color) {
super(color);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setTypeface(transTypeFaceBold);
//ds.setTypeface(Typeface.DEFAULT_BOLD);
}
}
private Type1Span touchedInstance;
public WordView(Context context) {
super(context);
init();
}
public WordView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public WordView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
Context ctx = getContext();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(ctx);
String defaultType = "sans";
String fontType = sp.getString(App.PreferenceKeys.preference_font_idx, defaultType);
if (!FONTS.containsKey(fontType)) fontType = defaultType;
transTypeFace = Typeface.createFromAsset(ctx.getAssets(), FONTS.get(fontType)[0]);
transTypeFaceBold = Typeface.createFromAsset(ctx.getAssets(), FONTS.get(fontType)[1]);
setTypeface(transTypeFaceBold);
setMovementMethod(LinkMovementMethod.getInstance());
setOnTouchListener(this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
ViewParent p = getParent();
if (p instanceof ScrollView)
parent = (ScrollView) p;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return event.getAction() == MotionEvent.ACTION_DOWN ?
true : super.onTouchEvent(event);
}
public void setWordInfo(String word, String translation, String text) {
infoWord = word;
translation = translation.trim();
translation = TextUtils.isEmpty(translation) ? "" : (translation + '\n');
setText(infoWord.trim().toUpperCase() + "\n" + translation + "\n"+ text);
}
@Override
public void setText(CharSequence text, BufferType type) {
Integer currentType = LinksFinder.getType(infoWord != null ? infoWord : ""); //XXX
ArrayList<LinksFinder.LinkSpec> links = LinksFinder.getLinks(text.toString());
if (links == null) {
super.setText(text, type);
return;
}
SpannableString ss = new SpannableString(text);
int links_length = links.size();
for (int i = 0; i < links_length; ++i) {
LinksFinder.LinkSpec l = links.get(i);
CharacterStyle span;
if (LinksFinder.TRANSCRIPTION == l.type) {
span = new TranscriptionTypeSpan(0xffc91111);
} else if (currentType == l.type) {
span = new Type2Span(l.url);
} else {
span = new Type1Span(l.url);
}
ss.setSpan(span, l.start, l.end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
super.setText(ss, type);
}
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN
|| event.getAction() == MotionEvent.ACTION_MOVE) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= getTotalPaddingLeft();
y -= getTotalPaddingTop();
int xx = getRealPosX(x);
int yy = getRealPosY(y);
x += getScrollX();
y += getScrollY();
Layout layout = getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
Type1Span[] candidates = ((Spannable) getText()).getSpans(off, off, Type1Span.class);
if (candidates.length > 0) {
touchedInstance = candidates[0];
} else {
touchedInstance = null;
}
if (mClickEnabled && popup != null && touchedInstance != null)
popup.setPopupText(xx, yy, touchedInstance.word);
} else {
if (popup != null)
popup.clear();
if (touchedInstance != null) {
touchedInstance = null;
}
}
return false;
}
public void setPopup(PopupView popup) {
this.popup = popup;
this.popup.setTypeFace(transTypeFaceBold);
}
private int getRealPosX(int val) {
return parent == null ? val : val - parent.getScrollX();
}
private int getRealPosY(int val) {
return parent == null ? val : val - parent.getScrollY();
}
public void setClickEnabled(boolean enabled) {
mClickEnabled = enabled;
}
}
WordAdapter.java
class WordAdapter extends CursorAdapter implements Filterable, DB {
private String[] QUERY_PROJECTION = new String[] { COLUMN_ID, COLUMN_WORD };
private final int WORD_COLUMN_INDEX;
private SQLiteDatabase db;
public WordAdapter(Context context, Cursor c, SQLiteDatabase db) {
super(context, c);
WORD_COLUMN_INDEX = c.getColumnIndexOrThrow(COLUMN_WORD);
this.db = db;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
final TextView view = (TextView) inflater.inflate(
R.layout.simple_dropdown_item_1line, parent, false);
view.setText(cursor.getString(WORD_COLUMN_INDEX));
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view).setText(cursor.getString(WORD_COLUMN_INDEX));
}
@Override
public String convertToString(Cursor cursor) {
return cursor.getString(WORD_COLUMN_INDEX);
}
@Override
public Cursor runQueryOnBackgroundThread(CharSequence s) {
Cursor c = null;
if (s != null)
c = db.query(DB.TABLE_WORDS, QUERY_PROJECTION, getLike(s.toString().toLowerCase()), null, null, null, null);
return c;
}
private String getLike(String s) {
return DB.COLUMN_WORD + ">= '" + s + "' AND " + DB.COLUMN_WORD + "< '" + s + '\u044F' +"'";
}
}