Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我如何在别人之后得出某些观点?_Java_Android_Android Layout_Android Custom View - Fatal编程技术网

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
    }
}