Java 我如何在别人之后得出某些观点?
我有一个简单的Java 我如何在别人之后得出某些观点?,java,android,android-layout,android-custom-view,Java,Android,Android Layout,Android Custom View,我有一个简单的LinearLayout,其中只包含一个扩展TextView(我将开始调用它“IdiomView”)的自定义视图和一个列表视图。IdiomView与普通TextView的唯一区别在于,我已经重写了onDraw()方法,以迭代方式减小文本大小,直到文本长度小于3行。我的问题是,绘制视图时,用户将看到: ______________ |__ACTION_BAR__| | IdiomView | |______________| | | | List
LinearLayout
,其中只包含一个扩展TextView
(我将开始调用它“IdiomView
”)的自定义视图和一个列表视图。IdiomView
与普通TextView
的唯一区别在于,我已经重写了onDraw()
方法,以迭代方式减小文本大小,直到文本长度小于3行。我的问题是,绘制视图时,用户将看到:
______________
|__ACTION_BAR__|
| IdiomView |
|______________|
| |
| ListView |
| |
| |
|______________|
很快就会变成:
______________
|__ACTION_BAR__|
|__IdiomView __|
| |
| ListView |
| |
| |
| |
|______________|
i、 e.绘制ListView,然后在IlimoView
整理出其大小后跳转
我想要的是一种方法,在绘制ListView之前,等待我的视图
完全绘制完成。这篇文章通过调用View.post(Runnable)
说明如何在绘图完成后排列线程。问题是我重写了onDraw()
方法多次调用onDraw()
,以计算较小的文本是否包含少于3行的内容,因此在我希望出现列表视图之前,此元素可能多次“完成绘制”
我感谢所有的评论和回答。以下是我当前的代码:
布局XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="@color/off_white"
android:orientation="vertical" >
<carter.cwords.idioms.IdiomView
android:id="@+id/idiom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:textColor="@color/transparent"
android:textSize="28sp"
android:textStyle="italic"
android:visibility="invisible" />
<ListView
android:id="@+id/quote_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:choiceMode="none"
android:footerDividersEnabled="false"
android:headerDividersEnabled="false"
android:visibility="invisible" />
</LinearLayout>
惯用视图
:
public class IdiomView extends TextView {
public IdiomView(Context context) {
super(context);
}
public IdiomView(Context context, AttributeSet attrs){
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.i(getClass().getSimpleName(), "onDraw(): " + this.getLineCount());
if(this.getLineCount() > 2){
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, this.getTextSize()-1);
}
else{
this.setTextColor(getResources().getColor(R.color.text));
}
Log.i(getClass().getSimpleName(), "onDraw(): " + this.getLineCount());
}
}
非常感谢。我以前从未在视图上尝试过此操作,但我认为它可以帮助您的应用程序在绘制惯用视图后,仅使用列表视图。您可以使用侦听器来实现这一点。但是,它将要求您使用代码隐藏方法
在idiom视图
中创建一个界面,例如
public static interface OnDrawComplete {
public abstract void onDrawComplete();
}
private OnDrawComplete mListener;
public IdiomView(Context context) {
super(context);
// this forces it to make sure it's actually an activity
// context so you can get a listener
if (context instanceof Activity)
this.mListener = context;
}
现在,在绘图的末尾,调用它
if (this.mListener != null)
this.mListener.onDrawComplete();
这将调用创建对象的活动并通知其绘图。因此,在您的活动中,您实现了接口
public void onDrawComplete() {
// After the draw completes, it calls this callback.
// setup the rest of your layout now
mQuoteList = (ListView) findViewById(R.id.quote_list);
this.populateQuoteList();
}
您还可以调用this.mListener.onDrawComplete()
在某种其他视图事件中,但我找不到合适的。您提到了View.post(runnable)
,它可能会起作用,但我也从未使用过类似的东西
最大的潜在问题是,我不知道idiom视图
将如何接收上下文或哪个上下文。在这种情况下,您需要实现接口的活动的上下文
如果没有获得正确的上下文,您可能需要手动实例化并将其添加到布局中以使用此方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mIdiomTextView = new mIdiomTextView(this);
// add to the Layout manually.
}
这里有更多的内容
习惯用法视图
public class IdiomView extends TextView {
public static interface OnDrawComplete {
public abstract void onDrawComplete();
}
private OnDrawComplete mListener;
public IdiomView(Context context) {
this(context, 0);
}
public IdiomView(Context context, AttributeSet attrs){
super(context, attrs);
if (context instanceof Activity)
this.mListener = context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// do your drawing code here
// ...
// after drawing, call the listener, which tells your
// Activity to deal with the ListView.
if (this.mListener != null)
this.mListener.onDrawComplete();
}
}
活动
public class MyActivity extends Activity implements IdiomView.OnDrawComplete {
//...
private IdiomView mIdiomTextView;
private ListView mQuoteList;
public void onDrawComplete() {
// After the draw completes, it calls this callback.
// setup the rest of your layout now
mQuoteList = (ListView) findViewById(R.id.quote_list);
this.populateQuoteList();
// now show the ListView
mQuoteList.setVisibility(View.Visible);
}
private void populateQuoteList() {
// populate your ListView here
}
}
重复设置文本大小直到找到合适的字体大小可能会非常低效,因为您的TextView
每次都需要重新测量和重新绘制。您可以使用其TextView.getPaint()
方法测量和设置文本一次,而不必这样做。您可以使用循环中的Paint
来测量文本,提供不同的字体大小,直到Paint.measureText()
返回的值低于小部件当前宽度的两倍。您可以使用它的getPaint来避免重复设置文本大小(同时重新绘制小部件)()
方法。使用该绘制
来测量循环中的文本宽度(具有不同的文本大小),直到您看到哪个值适合可用的最大宽度(到文本视图
)两次,并将该直接值用于文本sizeThanks Luksprog。这是我应该如何解决该问题的。提供了有关测量TextView
s的详细信息。这是一个极好的答案,完美地回答了我提出的问题。然而,在实现此答案后,我计算了Idi所用的时间omView
完成了画图,几乎花了半秒钟。我问的问题很糟糕,其他有同样问题的人应该看看Luksprog的评论(上图)who的方法大约需要50毫秒。很高兴你修复了它。看看Luksprog是否会添加它作为答案,这样你就可以接受它。循环直到宽度小于最大宽度的两倍,如果较长的单词覆盖到三分之一,仍然可以跨越三行,所以我只测量了最大高度。@WilliamCarter我忘了,你仍然可以测量宽度,但需要额外检查,以查看文本的一半位置(在单词或空白处),并从那里进行一些调整。
public class MyActivity extends Activity implements IdiomView.OnDrawComplete {
//...
private IdiomView mIdiomTextView;
private ListView mQuoteList;
public void onDrawComplete() {
// After the draw completes, it calls this callback.
// setup the rest of your layout now
mQuoteList = (ListView) findViewById(R.id.quote_list);
this.populateQuoteList();
// now show the ListView
mQuoteList.setVisibility(View.Visible);
}
private void populateQuoteList() {
// populate your ListView here
}
}