java - TabLayout 最终位于搜索栏(EditText)上方,我希望它位于搜索栏下方

标签 java android android-edittext

所以最初,我想为两个子 fragment 使用一个 SearchBar (EditText),但我不知道如何让它工作,所以我相反,在父 fragment 中,我有 TabLayoutViewpager,并且在两个子 fragment SearchUserFragmentSearchEventsFragment 我添加了一个带有搜索栏的工具栏。所以现在两个子 fragment 都有自己各自的SearchBar。

问题是 TabLayout 位于 fragment 中的 SearchBar 之上,我希望相反,因为 SearchBar 位于 TabLayout 之上>…

如果我的 TabLayout 和 Viewpager 位于主机 fragment 中,而工具栏位于子 fragment 中,如何才能实现此功能?

就像我说的,理想情况下我希望 SearchBar 仅位于父 fragment 中,但我已经尝试了很长时间,但我不知道该怎么做。我尝试在子 fragment 中公开这些方法,我尝试使用 Filterable,但我不知道该怎么做...

有人可以告诉我如何做我现在想做的事情吗? TabLayout(父 fragment )位于SearchBar(子 fragment )下方?

enter image description here

fragment_search.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_home_bnv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Fragment.SearchFragment">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        android:elevation="4dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:windowBackground"
            android:elevation="4dp"
            app:tabIconTint="@color/colorBlack"
            app:tabIndicatorColor="@color/colorBlack"
            app:tabRippleColor="?android:attr/windowBackground"
            app:tabTextColor="@color/colorBlack" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</LinearLayout>

fragment_search_users.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_search_users"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Fragment.SearchUsersFragment">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        android:elevation="4dp">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/windowBackground"
            android:elevation="4dp">

            <ImageView
                android:layout_width="27dp"
                android:layout_height="27dp"
                android:contentDescription="@string/icon_search_search_fragment"
                android:src="@drawable/ic_search_aqua" />

            <EditText
                android:id="@+id/search_bar"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:layout_marginStart="30dp"
                android:background="@android:color/transparent"
                android:hint="@string/search" />

        </androidx.appcompat.widget.Toolbar>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

fragment_search_events.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Fragment.SearchEventsFragment">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        android:elevation="4dp">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/windowBackground"
            android:elevation="4dp">

            <ImageView
                android:layout_width="27dp"
                android:layout_height="27dp"
                android:contentDescription="@string/icon_search_search_fragment"
                android:src="@drawable/ic_search_aqua" />

            <EditText
                android:id="@+id/search_bar"
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:layout_marginStart="30dp"
                android:background="@android:color/transparent"
                android:hint="@string/search" />

        </androidx.appcompat.widget.Toolbar>

    </com.google.android.material.appbar.AppBarLayout>


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

SearchFragment.java

public class SearchFragment extends Fragment {

    private DrawerLayout mDrawer;
    private Activity mActivity;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_search, container, false);

        ((DrawerLocker) getActivity()).setDrawerLocked(true);

        mDrawer = mActivity.findViewById(R.id.drawer_layout);

        final TabLayout tabLayout = v.findViewById(R.id.tab_layout);
        final ViewPager viewPager = v.findViewById(R.id.viewpager);

        tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.icon_people_black));
        tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.icon_event_available_black));

        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager());
        viewPagerAdapter.addFragment(new SearchUsersFragment(), "");  // new SearchUsersFragment() should be in `FragmentPagerAdapter.getItem()`
        viewPagerAdapter.addFragment(new SearchEventsFragment(), ""); // new SearchEventsFragment() should be in `FragmentPagerAdapter.getItem()`

        viewPager.setAdapter(viewPagerAdapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));

        return v;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        if (context instanceof Activity) {
            mActivity = (Activity) context;
        }
    }

    static class ViewPagerAdapter extends FragmentPagerAdapter {

        private ArrayList<Fragment> mFragments; // this line can cause crashes
        private ArrayList<String> mTitles;

        ViewPagerAdapter(@NonNull FragmentManager fm) {
            super(fm);
            this.mFragments = new ArrayList<>();
            this.mTitles = new ArrayList<>();
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        void addFragment(Fragment fragment, String title) {
            mFragments.add(fragment);  // this line can cause crashes
            mTitles.add(title);
        }

        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return mTitles.get(position);
        }
    }

    @Override
    public void onDestroy() {
        ((DrawerLocker) getActivity()).setDrawerLocked(false);
        super.onDestroy();
    }
}

SearchUsersFragment.java

public class SearchUsersFragment extends Fragment {

    RecyclerView mRecyclerView;
    UserAdapter mUserAdapter;
    List<User> mUserList;

    private EditText mSearchBar;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_search_users, container, false);

        mRecyclerView = view.findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        mUserList = new ArrayList<>();
        mUserAdapter = new UserAdapter(getContext(), mUserList, true);
        mRecyclerView.setAdapter(mUserAdapter);

        mSearchBar = view.findViewById(R.id.search_bar);
        mSearchBar.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                searchUsers(s.toString().toLowerCase());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        readUsers();

        return view;
    }

    public void searchUsers(String s) {
        Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("username").startAt(s).endAt(s + "\uf8ff");
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                mUserList.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    User user = snapshot.getValue(User.class);
                    mUserList.add(user);
                }

                mUserAdapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

    private void readUsers() {
        final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (mSearchBar.getText().toString().equals("")) {
                    mUserList.clear();
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        User user = snapshot.getValue(User.class);
                        if (firebaseUser != null && user != null && !user.getId().equals(firebaseUser.getUid())) {
                            mUserList.add(user);
                        }
                    }

                    mUserAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }
}

SearchEventsFragment.java

public class SearchEventsFragment extends Fragment {

    RecyclerView mRecyclerView;
    SearchEventsAdapter mSearchEventsAdapter;
    List<Post> mPostList;

    private EditText mSearchBar;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_search_events, container, false);

        mRecyclerView = view.findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

        mPostList = new ArrayList<>();
        mSearchEventsAdapter = new SearchEventsAdapter(getContext(), mPostList);
        mRecyclerView.setAdapter(mSearchEventsAdapter);

        mSearchBar = view.findViewById(R.id.search_bar);
        mSearchBar.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                searchEvents(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        readEvents();

        return view;
    }

    private void searchEvents(String s) {
        Query query = FirebaseDatabase.getInstance().getReference("Posts").orderByChild("text_event").startAt(s).endAt(s + "\uf8ff");
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                mPostList.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    Post post = snapshot.getValue(Post.class);
                    mPostList.add(post);
                }

                mSearchEventsAdapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }

    private void readEvents() {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (mSearchBar.getText().toString().equals("")) {
                    mPostList.clear();
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        Post post = snapshot.getValue(Post.class);
                        if (post != null) {
                            mPostList.add(post);
                        }
                    }

                    mSearchEventsAdapter.notifyDataSetChanged();
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }
}

最佳答案

问题是您绘制工具栏两次:第一次在容器屏幕中,第二次在 fragment (viewPager 项目)内。

<ImageView
    android:layout_width="27dp"
    android:layout_height="27dp"
    android:contentDescription="@string/icon_search_search_fragment"
    android:src="@drawable/ic_search_aqua" />

<EditText
    android:id="@+id/search_bar"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:layout_marginStart="30dp"
    android:background="@android:color/transparent"
    android:hint="@string/search" />

在fragment_search(主视图)中尝试此代码并从子级中删除AppBarLayout。

附:使用https://developer.android.com/reference/android/widget/SearchView而不是手动创建搜索 View 。

关于java - TabLayout 最终位于搜索栏(EditText)上方,我希望它位于搜索栏下方,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62267024/

相关文章:

Java - 如何验证当鼠标悬停在按钮上时是否显示替代文本?

java - Android 异步静态类?

java - 数据库备份到sd卡

android - 使用 Android 数据绑定(bind)创建双向绑定(bind)

java - 声明 editText java 时未使用局部变量

java - 将 java 对象序列化为 objective-c plist

java - 填充包含 '-' 的 flatXmlDataSetBuilder SQL-SERVER 表名

android - Android中如何知道哪个是前一个Activity?

android - 我怎样才能得到其他包中第二个顶级 Activity 的包名?

android - 为 EditText 的 HINT 设置多行