【问题标题】:Change TextView's height programatically on ViewPager's change在 ViewPager 更改时以编程方式更改 TextView 高度
【发布时间】:2015-01-14 07:11:42
【问题描述】:

我使用 ViewPager 和 4 个 Fragments 作为我的应用程序的某种介绍/手册。我的问题是当我到达最后一个片段时,它看起来像这样:

当用户单击“准备就绪”Button 时,我有一个动画来“折叠”标题(将其高度更改为 0 像素)并执行一些其他操作。我的意图是在用户导航到 ViewPager 的另一个片段时将视图重置为其原始状态(“展开”标题)。

要知道用户何时移动到另一个页面,我正在使用setUserVisibleHint,如下所示:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    if( !isVisibleToUser) {
        // Reset/expand the title's TextView
        if(mTitle != null) {
            int titlesHeight = mTitle.getMeasuredHeight();

            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mTitle.getLayoutParams();
            params.height = titlesHeight;

            mTitle.setLayoutParams(params);
            mTitle.invalidate();
            mTitle.requestLayout();
        }
        // Reset other views...
    }   
}

但这不起作用。

我尝试过的

我已经尝试了setLayoutParamsinvalidaterequestLayout 的所有可能组合,包括留下一个或多个并更改其顺序,但是当用户导航回第四页时,标题仍处于折叠状态。 我检查了这个方法是否被正确触发,titlesHeight != 0 每次和getText 仍然返回“标题”。 我重置了其他视图(为简单起见,我没有显示),例如我的屏幕截图中显示的Chronometer,一切都很好。

onPageSelected 和界面

界面

public interface FragmentAdapterNotificator {
    public void fragmentIsVisible();
    public void fragmentIsNotVisible();
}

mViewPager.setOnPageChangeListener()

Override
public void onPageSelected(int i) {
    FragmentAdapterNotificator fragment = (FragmentAdapterNotificator) mAdapter.instantiateItem(mViewPager, i);
    if (fragment != null) {
        fragment.fragmentIsVisible();
    }
}

片段实现接口

public class FragmentFour extends Fragment implements FragmentAdapterNotificator {
    @Override
        public void fragmentIsVisible() {
            // Reset/expand the title's TextView
            if(mTitle != null) {
                int titlesHeight = mTitle.getMeasuredHeight();

                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mTitle.getLayoutParams();
                params.height = titlesHeight;

                mTitle.setLayoutParams(params);
                mTitle.invalidate();
                mTitle.requestLayout();
            }
        }
}

有人知道这里发生了什么吗?

注意

我不想使用另一个Animation 来扩展标题,因为如果用户在另一个页面中,那么动画高度的恢复是没有意义的,因为用户不会看到它,所以我认为就性能最好使用“快捷方式”来避免动画。 我尝试使用“扩展”动画进行测试,效果很好,但我不想使用它。

附录

这是我的片段布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@android:color/transparent"
    android:clipChildren="false"
    android:padding="30dp" >

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/TextTitle"
        android:text="@string/tour_four_title" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:paddingTop="16dp" >

        <Chronometer
            android:id="@+id/chronometer"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textColor="#000000"
            android:textSize="30sp" />

        <Button
            android:id="@+id/ready"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="READY" />

    </LinearLayout>
    <!-- Some Stuff -->        
</LinearLayout>

“折叠”动画用于将 Title 的高度设置为 0:

public void collapseView(final View v) {
    final int initialHeight = v.getMeasuredHeight();
    Animation a = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if(interpolatedTime == 1){
                v.setVisibility(View.GONE);
            }else{
                v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
                v.requestLayout();
            }
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };
    a.setDuration(800);
    v.startAnimation(a);
}

“展开”动画:

public void expandView(final View v) {
    v.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    final int targetHeight = v.getMeasuredHeight();

    v.getLayoutParams().height = 0;
    v.setVisibility(View.VISIBLE);
    Animation a = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            v.getLayoutParams().height = interpolatedTime == 1
                    ? LayoutParams.WRAP_CONTENT
                    : (int)(targetHeight * interpolatedTime);
            v.requestLayout();
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };
    a.setDuration(1000);
    v.startAnimation(a);
}

和我的“reset”方法差不多,但是不知道为什么不行。

【问题讨论】:

    标签: android resize textview android-viewpager collapse


    【解决方案1】:

    所以基本上,据我了解,当用户离开页面时,您希望标题返回到其原始高度。而不是那为什么当用户返回原始片段时不将其设为默认值。让我解释一下,您在单击按钮时将标题设置为 0dp,用户导航离开,当他再次来到片段时,标题应该是 20dp,对吗?

    我猜可以这样完成,

    在你的 basic_activity(viewpager 被声明的地方)中创建一个类似

    的接口
     public interface FragmentInterface{
           void Fragmentbecamevisible();
    }
    

    现在向您的 viewPager 声明 setOnPageChangeListener,

     viewPager.setOnPageChangeListener(new OnPageChangeListener() {
    
    
            @Override
            public void onPageSelected(int arg0) {
                // TODO Auto-generated method stub
                actionBar.setSelectedNavigationItem(arg0);
                FragmentInterface frag=(FragmentInterface)mAdapter.instantiateItem(viewPager, arg0);
                if(frag!=null)
                {
                    frag.Fragmentbecamevisible();
                }
    
    
            }
    
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub
    
            }
    
            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub
    
            }
        });
    

    现在它的作用是,每次用户导航到一个片段时都会调用这个接口函数。

    在所有片段中实现接口。 更改您希望动画发生的片段中的功能。

    所以它会像,

    public class Your_Fragment extends Fragment implements FragmentInterface
    {
        public void Fragmentbecamevisible() {
        // TODO Auto-generated method stub
        //Do all the things with the TITLE here ..Iv done the same with a button.So you will be able to change the color and height of Title in here
    
    
    }
    
    
    }
    //Rest of the codes as well
    
    }
    

    因此,每次您导航到片段时,用户都会看到原始结构。

    希望这个方法有效。

    请在需要的地方进行编辑。

    【讨论】:

    • 不行,结果还是一样(TextView的高度还是0dp):(
    • @peguerosdc .. 尝试时发生了什么 .. 尝试在 Fragment 接口函数中放置一个 Toast 以确保在滑动发生时调用该函数。
    • 我已经编辑了我的问题 :) 并且我确信该函数已被调用,因为正如我所说,我重置了其他视图(如 Chronometer)并且它们已正确重置。但是,您的建议会在用户导航回 Fragment 时重置它,但是因为我使用的是 ViewPager,所以当用户因为滚动而离开它时,我需要重置 Fragment。
    • @peguerosdc ..ok..而用户导航离开..我想我有一个解决方案。等一下..同时在现有代码中..你为什么不再次设置文本片段接口函数连同 setTextSize 和 setHeight ...
    • 我会等,谢谢:)。并且再次设置文本也不起作用。
    【解决方案2】:

    感觉真的很愚蠢,但在“collapseView”中我有这个

    if(interpolatedTime == 1){
        v.setVisibility(View.GONE);
    }
    

    所以我的视图在我的重置方法中调整了大小,但是因为它已经消失了,所以我看不到它。我刚刚修改了它的可见性,瞧:

    // Reset/expand the title's TextView
    if(mTitle != null) {
        int titlesHeight = mTitle.getMeasuredHeight();
    
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mTitle.getLayoutParams();
        params.height = titlesHeight;
        mTitle.setLayoutParams(params);
        mTitle.setVisibility(View.VISIBLE);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-02-28
      • 2023-01-17
      • 2014-11-21
      • 2014-01-22
      • 2017-04-25
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      • 2015-09-30
      相关资源
      最近更新 更多