Android更改onDraw内部的视图宽度

时间:2014-04-28 18:11:23

标签: android android-view android-custom-view

我有一个ListView,其中将有垂直对齐的数据列,并且必须在添加新项目时进行更新。 LinearLayout上方ListView TextViewListView作为标题,还需要更改宽度以保持对齐。

添加项目时EditText会正确更新,但标题不会更新。

当屏幕键盘被拉入或推出视图时,标题似乎只会更新,方法是点击TextView窗口小部件或点击后退按钮。

我为Log创建了一个包装类,其中一些函数在super.whatever()之前和之后调用ListView类,以确定调用的内容和时间。

由此我可以看到,当某个项目添加到setWidth()时,需要更改宽度时,只会调用onDraw()ArrayAdapter

getView() TextView内部,我尝试调用invalidate()postInvalidate()LinearLayout之类的标题childDrawableStateChanged() {1}}保留标题setLayoutParams()之类的其他内容。我尝试使用setWidth()代替TextView。无论有没有这些功能,应用程序都会执行相同的操作。

如何告诉getView在绘制之前读取新的宽度,但是在ArrayAddapter的{​​{1}}内?

示例代码是显示带有2个简单文本项的ListView,其中添加Button会将EditText中的文本插入第1列,将“b”插入第2列。设置Button用于测试onPauseonResume的效果。

package testing;

import java.util.ArrayList;

import com.testing.R;

import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends ListActivity implements OnClickListener {

    TestArrayAdapter testAA;
    private MyTextView headerA, headerB;
    private LinearLayout headerLine;
    private EditText inputEditText;
    private Button addButton, settingsButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.main_layout);

        // get views and setup custom headers
        inputEditText = (EditText) this.findViewById(R.id.inputEditText);
        addButton = (Button) this.findViewById(R.id.addButton);
        settingsButton = (Button) this.findViewById(R.id.settingsButton);
        headerLine = (LinearLayout) this.findViewById(R.id.headerLineLayout);
        headerA = (MyTextView) new MyTextView(this);
        headerA.setText("H1");
        headerB = (MyTextView) new MyTextView(this);
        headerB.setText("H2");
        headerLine.addView(headerA);
        headerLine.addView(headerB);

        // get initial header width to set as max width
        int headerWidthA = (int) headerA.getPaint().measureText((String) headerA.getText());
        int headerWidthB = (int) headerB.getPaint().measureText((String) headerB.getText());

        // most likely redundant
        headerA.setWidth(headerWidthA);
        headerB.setWidth(headerWidthB);

        // setup listeners and adapter
        testAA = new TestArrayAdapter(this, R.layout.main_layout_line, new StringList());
        addButton.setOnClickListener(this);
        settingsButton.setOnClickListener(this);
        this.setListAdapter(testAA);

        // set header widths as initial max width
        testAA.strList.maxWidthA = headerWidthA;
        testAA.strList.maxWidthB = headerWidthB;

        Log.i("main", "onCreate");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.i("main", "onResume");
    }

    @Override
    public void onClick(View view) {

        if (view == this.findViewById(R.id.addButton))
            testAA.add(new StringLine(inputEditText.getText().toString()));
        if (view == this.findViewById(R.id.settingsButton))
            this.startActivity(new Intent(this, SettingsActivity.class));
    }

    class TestArrayAdapter extends ArrayAdapter<StringLine> {

        private StringList strList;

        public TestArrayAdapter(Context context, int res, StringList strList) {
            super(context, res, strList.items);
            this.strList = strList;
        }

        @Override
        public View getView(int pos, View convertView, ViewGroup parent) {

            Log.i("testAA", "getView start");
            // inflate row view
            LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View rowView = inflater.inflate(R.layout.main_layout_line, parent, false);

            // get items and set their text
            TextView itemA = (TextView) rowView.findViewById(R.id.itemText1);
            TextView itemB = (TextView) rowView.findViewById(R.id.itemText2);
            itemA.setText(strList.items.get(pos).a);
            itemB.setText(strList.items.get(pos).b);

            // determine the width of the text and if the header needs to be updated
            int itemWidthA = (int) itemA.getPaint().measureText((String) itemA.getText());
            if (itemWidthA <= strList.maxWidthA) {
                itemWidthA = strList.maxWidthA;
            } else {
                Log.i("testAA", "header changed");
                strList.maxWidthA = itemWidthA;
                headerA.setWidth(itemWidthA);
                // TELL HEADER TO REDRAW HERE
                headerA.invalidate();
                headerA.postInvalidate();
                headerLine.invalidate();
                headerLine.postInvalidate();
                headerLine.childDrawableStateChanged(headerA);
                testAA.notifyDataSetChanged();
            }
            itemA.setWidth(itemWidthA);

            Log.i("testAA", "getView end");
            return rowView;
        }
    }

    // list of for the array adapter
    class StringList {
        ArrayList<StringLine> items = new ArrayList<StringLine>();
        int maxWidthA, maxWidthB;

    }

    // line item for array adapter list
    class StringLine {
        public StringLine(String stringA) {
            a = stringA;
            b = "b";
        }

        String a, b;
    }

    // wrapper class 
    class MyTextView extends TextView {

        public MyTextView(Context context) {
            super(context);
        }

        @Override
        public void onDraw(Canvas canvas) {
            Log.i("header", "onDraw start " + this.getText() + " width - " + this.getWidth());
            super.onDraw(canvas);
            Log.i("header", "onDraw end " + this.getText() + " width - " + this.getWidth());
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            Log.i("header", "onMeasure start " + this.getText() + " width - " + this.getWidth());
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            Log.i("header", "onMeasure end " + this.getText() + " width - " + this.getWidth());
        }

        @Override
        public void layout(int l, int t, int r, int b) {
            Log.i("header", "layout start " + this.getText() + " width - " + this.getWidth());
            super.layout(l, t, r, b);
            Log.i("header", "layout end " + this.getText() + " width - " + this.getWidth());
        }

        @Override
        public void setWidth(int width) {
            Log.i("header", "setWidth start " + this.getText() + " width - " + this.getWidth());
            super.setWidth(width);
            Log.i("header", "setWidth end " + this.getText() + " width - " + this.getWidth());
        }
    }

}

main_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/settingsButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Settings" />

    <EditText
        android:id="@+id/inputEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" />

    <Button
        android:id="@+id/addButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add" />

    <LinearLayout
        android:id="@+id/headerLineLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

    </LinearLayout>

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

main_layout_line.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/itemText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <TextView
        android:id="@+id/itemText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

</LinearLayout>

Logcat(项目添加到ListView后H1的宽度必须为60)

application started
04-28 17:53:54.614: E/Trace(2780): error opening trace file: No such file or directory (2)
04-28 17:53:55.394: D/dalvikvm(2780): GC_FOR_ALLOC freed 72K, 7% free 2677K/2872K, paused 24ms, total 26ms
04-28 17:53:55.394: I/dalvikvm-heap(2780): Grow heap (frag case) to 3.336MB for 635812-byte allocation
04-28 17:53:55.424: D/dalvikvm(2780): GC_FOR_ALLOC freed 4K, 6% free 3294K/3496K, paused 31ms, total 31ms
04-28 17:53:55.464: D/dalvikvm(2780): GC_CONCURRENT freed <1K, 6% free 3305K/3496K, paused 4ms+3ms, total 36ms
04-28 17:53:55.484: I/header(2780): setWidth start H1 width - 0
04-28 17:53:55.484: I/header(2780): setWidth end H1 width - 0
04-28 17:53:55.484: I/header(2780): setWidth start H2 width - 0
04-28 17:53:55.484: I/header(2780): setWidth end H2 width - 0
04-28 17:53:55.494: I/main(2780): onCreate
04-28 17:53:55.494: I/main(2780): onResume
04-28 17:53:55.564: I/header(2780): onMeasure start H1 width - 0
04-28 17:53:55.574: I/header(2780): onMeasure end H1 width - 0
04-28 17:53:55.574: I/header(2780): onMeasure start H2 width - 0
04-28 17:53:55.574: I/header(2780): onMeasure end H2 width - 0
04-28 17:53:55.614: I/header(2780): layout start H1 width - 0
04-28 17:53:55.614: I/header(2780): layout end H1 width - 27
04-28 17:53:55.614: I/header(2780): layout start H2 width - 0
04-28 17:53:55.614: I/header(2780): layout end H2 width - 27
04-28 17:53:55.654: D/gralloc_goldfish(2780): Emulator without GPU emulation detected.
04-28 17:53:55.684: I/header(2780): onDraw start H1 width - 27
04-28 17:53:55.684: I/header(2780): onDraw end H1 width - 27
04-28 17:53:55.694: I/header(2780): onDraw start H2 width - 27
04-28 17:53:55.694: I/header(2780): onDraw end H2 width - 27
04-28 17:53:55.904: I/header(2780): onMeasure start H1 width - 27
04-28 17:53:55.904: I/header(2780): onMeasure end H1 width - 27
04-28 17:53:55.904: I/header(2780): onMeasure start H2 width - 27
04-28 17:53:55.954: I/header(2780): onMeasure end H2 width - 27
04-28 17:53:55.954: I/header(2780): layout start H1 width - 27
04-28 17:53:55.954: I/header(2780): layout end H1 width - 27
04-28 17:53:55.954: I/header(2780): layout start H2 width - 27
04-28 17:53:55.954: I/header(2780): layout end H2 width - 27
04-28 17:53:56.254: I/header(2780): onMeasure start H1 width - 27
04-28 17:53:56.254: I/header(2780): onMeasure end H1 width - 27
04-28 17:53:56.254: I/header(2780): onMeasure start H2 width - 27
04-28 17:53:56.264: I/header(2780): onMeasure end H2 width - 27
04-28 17:53:56.304: I/header(2780): onMeasure start H1 width - 27
04-28 17:53:56.304: I/header(2780): onMeasure end H1 width - 27
04-28 17:53:56.304: I/header(2780): onMeasure start H2 width - 27
04-28 17:53:56.304: I/header(2780): onMeasure end H2 width - 27
04-28 17:53:56.314: I/header(2780): layout start H1 width - 27
04-28 17:53:56.314: I/header(2780): layout end H1 width - 27
04-28 17:53:56.314: I/header(2780): layout start H2 width - 27
04-28 17:53:56.314: I/header(2780): layout end H2 width - 27
04-28 17:53:56.364: I/header(2780): onDraw start H1 width - 27
04-28 17:53:56.364: I/header(2780): onDraw end H1 width - 27
04-28 17:53:56.364: I/header(2780): onDraw start H2 width - 27
04-28 17:53:56.374: I/header(2780): onDraw end H2 width - 27
04-28 17:53:56.624: I/header(2780): onMeasure start H1 width - 27
04-28 17:53:56.624: I/header(2780): onMeasure end H1 width - 27
04-28 17:53:56.634: I/header(2780): onMeasure start H2 width - 27
04-28 17:53:56.634: I/header(2780): onMeasure end H2 width - 27
04-28 17:53:56.654: I/header(2780): onMeasure start H1 width - 27
04-28 17:53:56.654: I/header(2780): onMeasure end H1 width - 27
04-28 17:53:56.654: I/header(2780): onMeasure start H2 width - 27
04-28 17:53:56.664: I/header(2780): onMeasure end H2 width - 27
04-28 17:53:56.685: I/header(2780): layout start H1 width - 27
04-28 17:53:56.685: I/header(2780): layout end H1 width - 27
04-28 17:53:56.704: I/header(2780): layout start H2 width - 27
04-28 17:53:56.704: I/header(2780): layout end H2 width - 27
04-28 17:53:56.754: I/header(2780): onDraw start H1 width - 27
04-28 17:53:56.754: I/header(2780): onDraw end H1 width - 27
04-28 17:53:56.764: I/header(2780): onDraw start H2 width - 27
04-28 17:53:56.764: I/header(2780): onDraw end H2 width - 27
04-28 17:53:56.794: I/header(2780): onMeasure start H1 width - 27
04-28 17:53:56.794: I/header(2780): onMeasure end H1 width - 27
04-28 17:53:56.794: I/header(2780): onMeasure start H2 width - 27
04-28 17:53:56.794: I/header(2780): onMeasure end H2 width - 27
04-28 17:53:56.844: I/header(2780): onMeasure start H1 width - 27
04-28 17:53:56.844: I/header(2780): onMeasure end H1 width - 27
04-28 17:53:56.844: I/header(2780): onMeasure start H2 width - 27
04-28 17:53:56.844: I/header(2780): onMeasure end H2 width - 27
04-28 17:53:56.844: I/header(2780): layout start H1 width - 27
04-28 17:53:56.855: I/header(2780): layout end H1 width - 27
04-28 17:53:56.855: I/header(2780): layout start H2 width - 27
04-28 17:53:56.855: I/header(2780): layout end H2 width - 27
04-28 17:53:56.884: I/header(2780): onDraw start H1 width - 27
04-28 17:53:56.884: I/header(2780): onDraw end H1 width - 27
04-28 17:53:56.894: I/header(2780): onDraw start H2 width - 27
04-28 17:53:56.894: I/header(2780): onDraw end H2 width - 27
text entered and clicked add
04-28 17:54:29.965: I/testAA(2780): getView start
04-28 17:54:29.975: I/testAA(2780): header changed
04-28 17:54:29.975: I/header(2780): setWidth start H1 width - 27
04-28 17:54:29.975: I/header(2780): setWidth end H1 width - 27
04-28 17:54:29.975: I/testAA(2780): getView end
04-28 17:54:29.985: I/testAA(2780): getView start
04-28 17:54:29.995: I/testAA(2780): getView end
04-28 17:54:30.005: I/header(2780): onDraw start H1 width - 27
04-28 17:54:30.005: I/header(2780): onDraw end H1 width - 27
04-28 17:54:30.005: I/header(2780): onDraw start H2 width - 27
04-28 17:54:30.005: I/header(2780): onDraw end H2 width - 27
04-28 17:54:30.035: I/header(2780): onDraw start H1 width - 27
04-28 17:54:30.045: I/header(2780): onDraw end H1 width - 27
04-28 17:54:30.045: I/header(2780): onDraw start H2 width - 27
04-28 17:54:30.045: I/header(2780): onDraw end H2 width - 27
clicked Back Button to lower keyboard
04-28 17:54:56.755: I/header(2780): onMeasure start H1 width - 27
04-28 17:54:56.755: I/header(2780): onMeasure end H1 width - 27
04-28 17:54:56.765: I/header(2780): onMeasure start H2 width - 27
04-28 17:54:56.765: I/header(2780): onMeasure end H2 width - 27
04-28 17:54:56.765: I/testAA(2780): getView start
04-28 17:54:56.795: I/testAA(2780): getView end
04-28 17:54:56.865: I/header(2780): onMeasure start H1 width - 27
04-28 17:54:56.875: I/header(2780): onMeasure end H1 width - 27
04-28 17:54:56.875: I/header(2780): onMeasure start H2 width - 27
04-28 17:54:56.875: I/header(2780): onMeasure end H2 width - 27
04-28 17:54:56.875: I/testAA(2780): getView start
04-28 17:54:56.885: I/testAA(2780): getView end
04-28 17:54:56.895: I/header(2780): layout start H1 width - 27
04-28 17:54:56.925: I/header(2780): layout end H1 width - 60
04-28 17:54:56.925: I/header(2780): layout start H2 width - 27
04-28 17:54:56.925: I/header(2780): layout end H2 width - 27
04-28 17:54:56.985: I/header(2780): onDraw start H1 width - 60
04-28 17:54:56.985: I/header(2780): onDraw end H1 width - 60
04-28 17:54:56.985: I/header(2780): onDraw start H2 width - 27
04-28 17:54:56.995: I/header(2780): onDraw end H2 width - 27
header updated

0 个答案:

没有答案