问题
I'm new to Android development, but I have quite some bit of Swing/WPF(C#) GUI experience. What I'm trying to do is the following:
I have a BottomNavigationView
with 3 separate views. Each view is implemented as a fragment that is shown/ hidden in the MainActivity java code through a OnNavigationItemSelectedListener
:
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.one:
findViewById(R.id.one).setVisibility(View.VISIBLE);
findViewById(R.id.two).setVisibility(View.GONE);
findViewById(R.id.threee).setVisibility(View.GONE);
return true;
// ... and so on
My problem is that a part of the interface of two of the fragments is identical and made of a set of EditText
and ImageButton
. So I thought of creating something re-usable instead of doubling the code. My options are to make a fragment inside a fragment (but around the internet I saw that this is not advisable) or to make a re-usable view (https://developer.android.com/training/improving-layouts/reusing-layouts.html, https://developer.android.com/guide/topics/ui/custom-components.html). What is the best way to do it? I'd like to have a xml layout with a connected java code, where I can listen to the interactions with the EditText
and the Buttons
and act accordingly. Maybe I'm biased by my WPF experience but I'm trying to make it like a xaml + codebehind, which may not be the correct way to tackle the problem when building Android apps.
回答1:
You will have to define a separate XML layout for a View that you will use more than once and
In XML
You will use the <include>
Tag inside your layout like
...
<include layout="@layout/your_frequent_used_layout"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:padding="10dp" />
....
More information here in the documentation training!
In Java
For Java side If you want to get a certain view and add to your current layout you will need a layout Inflater and then add to your View
like this in your activity (In your fragment consider contexts if it throws any errors)
1st Option:
View view = null;
LayoutInflater inflater =
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.your_reusable_view, null);
your_main_root_view.addView(view);
2nd Option:
View child = getLayoutInflater().inflate(R.layout.your_reusable_view, null);
your_main_root_view.addView(child);
回答2:
As per your code in the question, you are just showing/hiding the views present in the layout.
So, firstly I would suggest using BottomNavigationView in conjunction with a ViewPager and creating independent Fragments for every navigation item.
This article demonstrates how to get started
http://droidmentor.com/bottomnavigationview-with-viewpager-android/
Secondly, for all the fragments that contain common items, you will create an abstract BaseFragment that will manage all the common logic.
Extend this abstract fragment to create your individual fragments and Inflate the unique layouts.
fragment_base.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--- Your Common Elements Here --->
<!--- Unique Elements will get inserted here --->
</LinearLayout>
fragment_nav_unique1.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--- Unique Elements For the Nav View Item --->
</LinearLayout>
BaseFragment.java
public abstract class BaseFragment extends Fragment {
// Get Layout resource id of the Individual Fragments
protected abstract int layoutResourceId();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Inflate the base layout
LinearLayout view = (LinearLayout) inflater.inflate(R.layout.fragment_base, container, false);
// Inflate the unique layouts and add them to the view
LinearLayout uniqueView = (LinearLayout) inflater.inflate(layoutResourceId(), null);
view.addView(uniqueView);
// Return view
return view;
}
//--- Manage all the Common Elements here ---
}
FirstFragment.java
public class FirstFragment extends BaseFragment {
@Override
protected int layoutResourceId() {
// Return the resource of the unique layout
return R.layout.fragment_nav_unique1;
}
//--- Manage all the Unique Elements here ---
}
回答3:
Using CustomView is the way to go for this. Not only you can use the same layout file in this but can also define similar interactions with this view in your custom view implementation.
来源:https://stackoverflow.com/questions/47238178/reusable-views