如何在onSizeChanged中设置大小和布局?

时间:2011-06-07 08:02:28

标签: android listview resize refresh

我无法让我的元素(例如ListView)正确调整大小。

我有一个ListActivity用于搜索,带有仪表板,编辑框和列表视图。我们的想法是在键盘显示时隐藏操作栏。

我扩展了LinearLayout,以收听视图尺寸更改(按照建议here):

public class SizeChangingLinearLayout extends LinearLayout {
    //...
    @Override
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld)
    {        
        View actionbar = mainView.findViewById(R.id.actionbar);

        if (yNew > yOld) 
            actionbar.setVisibility(View.VISIBLE);
        else if (yNew < yOld) 
            actionbar.setVisibility(View.GONE);

        super.onSizeChanged(xNew, yNew, xOld, yOld);

    }
}

操作栏的隐藏/显示按预期工作,但在与隐藏操作栏相同高度的ListView下方有一个间隙。一旦图形发生任何变化(例如在编辑框中书写),ListView就会填补空白。隐藏键盘时,反向出现类似的行为。

enter image description here

[编辑]

更改其他布局时也会出现同样的问题。更改Visibility中的onSizeChanged项内容会直接显示,但在其他一些用户操作重新绘制这些视图之前,不会显示更改的大小和边距。失效不适用于onSizeChanged

[/编辑]

我试图通过以下方式刷新图形:

  • invalidate - 两个习惯 LinearLayout和ListView(如 建议here
  • 列表上的
  • notifyDataSetChanged 适配器
  • forceLayout

......还有更多,没有成功。为什么ListView最初没有调整大小?我是否必须在扩展的LinearLayout中覆盖onLayout?我错过了什么?

4 个答案:

答案 0 :(得分:35)

onSizeChanged()末尾添加以下内容将解决它:

Handler handler = new Handler();
handler.post(new Runnable() {

    @Override
    public void run() {
        requestLayout();
    }
});

请参阅此问题的答案:Views inside a custom ViewGroup not rendering after a size change

答案 1 :(得分:0)

这可能是一个长镜头......

您是否尝试使用android:layout_height=""的<{1}}设置?

使用ListViewmatch_parent可能会迫使它发挥作用......

正如我所说......一个长镜头!

答案 2 :(得分:0)

您可以通过将其高度更改为1px并调用

来强制ListView重绘

requestLayout()

答案 3 :(得分:0)

通过向setOnFocusChangeListener注册setOnClickListenerEditText,可以执行您想要的操作。

在导航方面需要考虑很多不同的场景,可能需要更改某些场景才能使用某些布局。

无论如何,首先重写onSizeChanged以在触摸后退按钮时显示隐藏元素。

public class MyLinearLayout extends LinearLayout {

    private MyListActivity mMyListActivity;

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

    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);      
    }

    public void setMyListActivity(MyListActivity mla) {
        mMyListActivity = mla;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // show the element when we get more room       
        if (h > oldh) {
            if (mMyListActivity != null) {
                mMyListActivity.showBar();
            }
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

在ListActivity中,我们抓住MyLinearLayout并将this传递给它。然后注册setOnFocusChangeListener以在EditText的焦点更改时处理事物。当EditText已经有焦点时,setOnClickListener用于隐藏元素。

public class MyListActivity extends ListActivity {

    private ArrayList<MyData> mDataList = new ArrayList<MyData>();

    private MyLinearLayout mMyLinearLayout; 
    private LinearLayout mHideMeLinearLayout;
    private EditText mEditText;

    public void showBar() {
        if (mHideMeLinearLayout != null) {
            mHideMeLinearLayout.setVisibility(View.VISIBLE);
        }
    }

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

        // Get MyLinearLayout and pass this to it.
        mMyLinearLayout = (MyLinearLayout) findViewById(R.id.myLinearLayout);
        mMyLinearLayout.setMyListActivity(this);

        // the LinearLayout to be hidden
        mHideMeLinearLayout = (LinearLayout) findViewById(R.id.LinearLayoutToHide);

        mEditText = (EditText) findViewById(R.id.editText);     
        mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
                if (hasFocus) {
                    imm.showSoftInput(mEditText, 0);
                    mHideMeLinearLayout.setVisibility(View.GONE);
                } else {
                    imm.hideSoftInputFromWindow(mMyLinearLayout.getWindowToken(), 0);
                    mHideMeLinearLayout.setVisibility(View.VISIBLE);
                }
            }
        });
        mEditText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mHideMeLinearLayout.setVisibility(View.GONE);
            }
        });

        .....
    }

    .....
}

我稍后会提供一个工作示例,但现在必须运行。