【问题标题】:How to create a vertical pagination with a fixed view如何使用固定视图创建垂直分页
【发布时间】:2015-12-19 17:09:46
【问题描述】:

我有 4 个片段,我想创建一种垂直视图分页器,但我需要保持前一页的视图可见。

更多细节:
片段 A 在底部有一个 TextView (TV1) 和其他视图。
片段 B 在底部有一个 TextView (TV2) 和其他视图。
片段 C 在底部有一个 TextView (TV3) 和其他视图。
我启动我的 Activity,Fragment A 占据了整个布局。
单击一个按钮 -> 片段 A 向上滑动并出现片段 B,但 TV1 仍应可见并固定在屏幕顶部。
单击一个按钮 -> 片段 B 向上滑动并出现片段 C,但 TV2 仍应可见并固定在屏幕顶部(TV2 应替换 TV1)...
如果我点击 TV2,片段 B 将重新出现在片段 B 上方。

我怎样才能获得这种行为?

【问题讨论】:

  • 我认为这可能是您使用Fragment 的地方,但应该在1 Fragment 中使用CustomView。那么你想要的行为就容易多了
  • @Blundell 感谢您的回复。你能告诉我更多细节吗?

标签: android android-layout android-fragments android-view


【解决方案1】:

我终于设法实现了类似于您所询问的内容。下面是它的外观:

这可能有点 hacky,不过我就是这样存档的:

首先,我需要一些TvFragment

public class TvFragment extends android.support.v4.app.Fragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.tv_fragment, container, false);
        TextView textView = (TextView)rootView.findViewById(R.id.tvTextView);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ((OnScrollChanged)getActivity()).onScroll(TvFragment.this);
            }
        });

        return rootView;
    }

    public void display(int height, String tvTitle, int backgroundColor) {
        if (getView() == null) {
            return;
        }

        ViewGroup.LayoutParams params = getView().getLayoutParams();
        params.height = height;
        getView().setLayoutParams(params);

        TextView textView = (TextView)getView().findViewById(R.id.tvTextView);
        textView.setText(tvTitle);
        getView().setBackgroundColor(backgroundColor);
    }
}

它是tv_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:layout_gravity="bottom"
        android:id="@+id/tvTextView"
        android:gravity="center"
        android:textColor="#FFFFFF"
        android:textSize="24sp"
        android:background="@drawable/textview_backgroud_selector"
        android:padding="8dp"
        android:layout_margin="@dimen/tv_button_margin"
        android:layout_width="match_parent"
        android:layout_height="@dimen/tv_button_height" />
</FrameLayout>

然后我们需要用我们的 Fragment 填充Activity

然后,我们需要一个适配器来填充我们的片段:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <fragment
            android:id="@+id/fragmentA"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:name="klogi.com.verticalpagination.TvFragment"/>
        <fragment
            android:id="@+id/fragmentB"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:name="klogi.com.verticalpagination.TvFragment"/>
        <fragment
            android:id="@+id/fragmentC"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:name="klogi.com.verticalpagination.TvFragment"/>
    </LinearLayout>
</ScrollView>

即我们将所有三个片段放在一个 ScrollView 中。

小助手interface在fragment和activity之间进行通信:

public interface OnScrollChanged {
    void onScroll(Fragment fragment);
}

最后一块是MainActivity class:

public class MainActivity extends AppCompatActivity implements OnScrollChanged {

    TvFragment fragmentA;
    TvFragment fragmentB;
    TvFragment fragmentC;

    int bigFragmentHeight;
    int smallFragmentHeight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportActionBar().hide();

        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        bigFragmentHeight = metrics.heightPixels - getStatusBarHeight();
        smallFragmentHeight = bigFragmentHeight - getResources().getDimensionPixelSize(R.dimen.tv_button_height) - 2 * getResources().getDimensionPixelSize(R.dimen.tv_button_margin);

        fragmentA = (TvFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentA);
        fragmentA.display(bigFragmentHeight, "TV1", Color.BLUE);

        fragmentB = (TvFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentB);
        fragmentB.display(smallFragmentHeight, "TV2", Color.RED);

        fragmentC = (TvFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentC);
        fragmentC.display(smallFragmentHeight, "TV3", Color.YELLOW);

        ScrollView scrollView = (ScrollView)findViewById(R.id.scrollView);
        scrollView.setOnTouchListener( new View.OnTouchListener(){
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });
    }

    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }

        return result;
    }

    @Override
    public void onScroll(Fragment fragment) {
        ScrollView scrollView = (ScrollView)findViewById(R.id.scrollView);
        int currentScroll = scrollView.getScrollY();

        if (fragment.equals(fragmentA)) {
            if (currentScroll == 0) {
                scrollView.smoothScrollTo(0, smallFragmentHeight);
            } else {
                scrollView.smoothScrollTo(0, 0);
            }
        } else if (fragment.equals(fragmentB)) {
            if (currentScroll == smallFragmentHeight) {
                scrollView.smoothScrollTo(0, smallFragmentHeight + bigFragmentHeight);
            } else {
                scrollView.smoothScrollTo(0, smallFragmentHeight);
            }
        } else if (fragment.equals(fragmentC)) {
            // do nothing
        }
    }
}

我在这里做什么 - 是禁用 ScrollView 的“正常”滚动,并取决于单击了哪个片段的按钮 - 向上或向下平滑滚动。

我也使用了以下资源: 尺寸:

<resources>
    <dimen name="tv_button_height">48dp</dimen>
    <dimen name="tv_button_margin">8dp</dimen>
</resources>

颜色:

<resources>
    <color name="textview_backgroud">#AAAAAA</color>
    <color name="textview_backgroud_pressed">#777777</color>
</resources>

和 textview_backgroud_selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/textview_backgroud_pressed"/>
    <item android:color="@color/textview_backgroud"/>
</selector>

我已将完整的项目上传到我的 Dropbox - feel free to check it out

就是这样!希望对你有帮助

【讨论】:

    猜你喜欢
    • 2015-01-05
    • 2020-11-09
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 2014-09-15
    • 1970-01-01
    • 2019-05-30
    • 2018-01-07
    相关资源
    最近更新 更多