Android 使子视图与父视图的宽度匹配

Android 使子视图与父视图的宽度匹配,android,layout,scrollview,Android,Layout,Scrollview,我有一个水平滚动视图,其中有许多EditText子对象。我希望这些子对象的宽度与父scrollview的可见区域的宽度相同。这在XML中是可能的吗 对于您的editText,当您将layout\u width或height设置为match\u parent时,它们将匹配父项设置为的任何大小。但是,一旦内容被文本填充,它们的维度就会扩展,因此具有与滚动视图相同的宽度/高度您可以编写一个小的帮助器类: 我们正在创建一个非常小的类,它扩展了EditText,名为FullWidthEditText,如下

我有一个水平滚动视图,其中有许多EditText子对象。我希望这些子对象的宽度与父scrollview的可见区域的宽度相同。这在XML中是可能的吗

对于您的
editText
,当您将
layout\u width
height
设置为
match\u parent
时,它们将匹配父项设置为的任何大小。但是,一旦内容被文本填充,它们的维度就会扩展,因此具有与
滚动视图相同的宽度/高度

您可以编写一个小的帮助器类:

我们正在创建一个非常小的类,它扩展了
EditText
,名为
FullWidthEditText
,如下所示:

package com.YOURPACKAGENAME;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import android.widget.HorizontalScrollView;

public class FullWidthEditText extends EditText {
    public FullWidthEditText(Context context) { super(context);}    
    public FullWidthEditText(Context context, AttributeSet attrs) { super(context, attrs); }
    public FullWidthEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        View parentScrollView=((View)(getParent().getParent()));

        if (parentScrollView!=null) {
            // check the container of the container is an HorizontallScrollView
            if (parentScrollView instanceof HorizontalScrollView) {
                // Yes it is, so change width to HSV's width
                widthMeasureSpec=parentScrollView.getMeasuredWidth();
            }
        }
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    }
}
现在您已经创建了这个类,您可以在XML中使用它,就像普通的EditText一样:

<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/horizontalScrollView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffff0000" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_marginRight="5dp"
        android:orientation="horizontal" >

        <com.YOURPACKAGENAME.FullWidthEditText
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:id="@+id/yourEditTextId">
        </com.YOURPACKAGENAME.FullWidthEditText>

        <com.YOURPACKAGENAME.FullWidthEditText
            android:layout_width="wrap_content"
            android:layout_height="match_parent" >
        </com.YOURPACKAGENAME.FullWidthEditText>
        .
        .
        .
    </LinearLayout>
</HorizontalScrollView>
  • 请注意,此解决方案也适用于任何其他小部件。如果您需要ie.一个全宽按钮,只需将
    扩展编辑文本
    更改为
    扩展按钮
    即可

  • 您可以轻松自定义大小,关键行是:
    widthMeasureSpec=parentScrollView.getMeasuredWidth()这样你就可以把全宽减10或20像素,把半宽,等等


希望有帮助

我认为
ViewPager
应该更合适,但也许您可以尝试以下视图层次结构:

  • HorizontalScrollView
    width=MATCH\u PARENT
    weightSum=1
    • LinearLayout
      orientation=HORIZONTAL
      weight=3
      weightSum=3
      • LinearLayout
        (第1页,
        orientation=VERTICAL
        weight=1
        • EditText
          width=MATCH\u PARENT
      • 线性布局
        (第2页,
        方向=垂直
        重量=1
        • EditText
          width=MATCH\u PARENT
      • 线性布局
        (第3页,
        方向=垂直
        重量=1
        • EditText
          width=MATCH\u PARENT

注意:我还没有测试过它。

尽管可以使用水平滚动视图进行测试。我发现使用查看寻呼机要容易得多。在我看来,它也更干净,可以让刷卡更顺畅

添加xml

  <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="70dp"/>
适配器

public class CustomPagerAdapter extends PagerAdapter {
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        LayoutInflater inflater = (LayoutInflater) container.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View page= inflater.inflate(R.layout.page_item, container, false);

        TextView textView =(TextView)page.findViewById(R.id.textView);


        textView.setText("Text");

        container.addView(page);
        return(page);
    }

    @Override
    public void destroyItem(ViewGroup container, int position,
                            Object object) {
        container.removeView((View)object);
    }

    @Override
    public int getCount() {
        return 16;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals( object );
    }


}

我发现一些边缘案例,rupps发布的
FullWidthEditText
不起作用,因此我修改了它,使其适用于我发现的所有案例:

public class FullWidthTextView extends android.support.v7.widget.AppCompatTextView
{
    public FullWidthTextView( final Context context )
    {
        super( context );
    }

    public FullWidthTextView( final Context context, @Nullable final AttributeSet attrs )
    {
        super( context, attrs );
    }

    public FullWidthTextView( final Context context, @Nullable final AttributeSet attrs, final int defStyleAttr )
    {
        super( context, attrs, defStyleAttr );
    }

    @Override
    protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
    {
        View parentScrollView = ((View) (getParent().getParent()));

        boolean needsRemeassure = false;

        if( parentScrollView != null )
        {
            // check the container of the container is an HorizontallScrollView
            if( parentScrollView instanceof HorizontalScrollView )
            {
                // Yes it is, so change width to HSV's width
                int parentWidth = parentScrollView.getMeasuredWidth();
                if( parentWidth > 0 )
                {
                    widthMeasureSpec = parentWidth;
                }
                // It's possible for the parent to still have ZERO width
                // in this case we must request to be remeassured
                else
                {
                    needsRemeassure = true;
                }
            }
        }

        super.onMeasure( widthMeasureSpec, heightMeasureSpec );

        setMeasuredDimension( View.MeasureSpec.makeMeasureSpec( widthMeasureSpec, MeasureSpec.EXACTLY ),
                              View.MeasureSpec.makeMeasureSpec( getMeasuredHeight(), MeasureSpec.EXACTLY ) );

        if( needsRemeassure )
        {
            post( new Runnable()
            {
                @Override
                public void run()
                {
                    requestLayout();
                }
            } );
        }
    }
}

视您的内容而定,ViewPager并不更合适?对
edittext
使用
android:layout\u width=“wrap\u content”
,并赋予此属性
android:minWidth=“80dp”
(任何适合的大小)并为屏幕大小保留单独的布局:)@alex-是的,我应该使用ViewPager。我现在在我的新项目中使用它。有趣的属性weightsum,不知道它,但是,由于以下几个原因,这将不起作用:(1)您不能将weight/sum指定给第一个linearlayout,因为HorizontalScrollView不是一个linearlayout,而是一个FrameLayout。(2) 您必须将第一台HScrollV包装到另一个线性布局中,才能在那里使用重量。。此外,布局处理器需要12或24次通过(!!!)来测量所有这些,带权重的线性布局是多通道布局,嵌套它们会使情况成倍恶化!如果内容类似于listview、gridview或许多视图,则您的答案是正确的。但是,对于(仅)多个EditText,我不认为创建一个ViewPager和(主要)一个适配器是一种节省资源的方法来实现这一点。我也尝试将此解决方案用于RelativeLayout,但子视图没有显示。。你有解决办法吗?我面临着完全相同的问题。你找到解决办法了吗?
public class CustomPagerAdapter extends PagerAdapter {
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        LayoutInflater inflater = (LayoutInflater) container.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View page= inflater.inflate(R.layout.page_item, container, false);

        TextView textView =(TextView)page.findViewById(R.id.textView);


        textView.setText("Text");

        container.addView(page);
        return(page);
    }

    @Override
    public void destroyItem(ViewGroup container, int position,
                            Object object) {
        container.removeView((View)object);
    }

    @Override
    public int getCount() {
        return 16;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals( object );
    }


}
public class FullWidthTextView extends android.support.v7.widget.AppCompatTextView
{
    public FullWidthTextView( final Context context )
    {
        super( context );
    }

    public FullWidthTextView( final Context context, @Nullable final AttributeSet attrs )
    {
        super( context, attrs );
    }

    public FullWidthTextView( final Context context, @Nullable final AttributeSet attrs, final int defStyleAttr )
    {
        super( context, attrs, defStyleAttr );
    }

    @Override
    protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec )
    {
        View parentScrollView = ((View) (getParent().getParent()));

        boolean needsRemeassure = false;

        if( parentScrollView != null )
        {
            // check the container of the container is an HorizontallScrollView
            if( parentScrollView instanceof HorizontalScrollView )
            {
                // Yes it is, so change width to HSV's width
                int parentWidth = parentScrollView.getMeasuredWidth();
                if( parentWidth > 0 )
                {
                    widthMeasureSpec = parentWidth;
                }
                // It's possible for the parent to still have ZERO width
                // in this case we must request to be remeassured
                else
                {
                    needsRemeassure = true;
                }
            }
        }

        super.onMeasure( widthMeasureSpec, heightMeasureSpec );

        setMeasuredDimension( View.MeasureSpec.makeMeasureSpec( widthMeasureSpec, MeasureSpec.EXACTLY ),
                              View.MeasureSpec.makeMeasureSpec( getMeasuredHeight(), MeasureSpec.EXACTLY ) );

        if( needsRemeassure )
        {
            post( new Runnable()
            {
                @Override
                public void run()
                {
                    requestLayout();
                }
            } );
        }
    }
}