如何访问活动内部/从活动中的片段视图组件
Posted
技术标签:
【中文标题】如何访问活动内部/从活动中的片段视图组件【英文标题】:How to access fragment views components inside/from activity 【发布时间】:2021-06-13 05:01:47 【问题描述】:我将导航抽屉与新组件 NavController 一起使用,我有七个片段,每个片段代表导航抽屉菜单项
我需要从MainActivity
访问每个片段中的一些视图组件,例如 Recyclerview 和 Adapter,以便像这样在 onOptionsItemSelected
上使用它
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item)
if (item.getItemId() == R.id.change_layout)
android.app.AlertDialog.Builder builder
= new android.app.AlertDialog.Builder(getContext());
builder.setTitle(getString(R.string.choose_layout));
String[] recyclerViewLayouts = getResources().getStringArray(R.array.RecyclerViewLayouts);
SharedPreferences.Editor editor = sharedPreferences.edit();
builder.setItems(recyclerViewLayouts, (dialog, index) ->
switch (index)
case 0: // Card List Layout
adapter.setViewType(0);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "cardLayout");
editor.apply();
break;
case 1: // Cards Magazine Layout
adapter.setViewType(1);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "cardMagazineLayout");
editor.apply();
break;
case 2: // PostTitle Layout
adapter.setViewType(2);
recyclerView.setLayoutManager(titleLayoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "titleLayout");
editor.apply();
break;
case 3: //Grid Layout
adapter.setViewType(3);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(adapter);
editor.putString("recyclerViewLayout", "gridLayout");
editor.apply();
);
android.app.AlertDialog alertDialog = builder.create();
alertDialog.show();
return true;
return super.onOptionsItemSelected(item);
我需要在所有片段上实现这个方法,而不是在每个片段中单独覆盖它
mobile_navigation xml
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
app:startDestination="@id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="com.test.dummyappv3.ui.home.HomeFragment"
android:label="@string/home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/nav_Accessory"
android:name="com.test.dummyappv3.ui.accessory.AccessoryFragment"
android:label="@string/accessory"
tools:layout="@layout/fragment_accessory" />
<fragment
android:id="@+id/nav_Arcade"
android:name="com.test.dummyappv3.ui.arcade.ArcadeFragment"
android:label="@string/arcade"
tools:layout="@layout/fragment_arcade" />
<fragment
android:id="@+id/nav_Fashion"
android:name="com.test.dummyappv3.ui.fashion.FashionFragment"
android:label="@string/fashion"
tools:layout="@layout/fashion_fragment" />
<fragment
android:id="@+id/nav_Food"
android:name="com.test.dummyappv3.ui.food.FoodFragment"
android:label="@string/food"
tools:layout="@layout/food_fragment" />
<fragment
android:id="@+id/nav_Heath"
android:name="com.test.dummyappv3.ui.heath.HeathFragment"
android:label="@string/heath"
tools:layout="@layout/heath_fragment" />
<fragment
android:id="@+id/nav_Lifestyle"
android:name="com.test.dummyappv3.ui.lifestyle.LifestyleFragment"
android:label="@string/lifestyle"
tools:layout="@layout/lifestyle_fragment" />
<fragment
android:id="@+id/nav_Sports"
android:name="com.test.dummyappv3.ui.sports.SportsFragment"
android:label="@string/sports"
tools:layout="@layout/sports_fragment" />
</navigation>
在 MainActivtiy 这个方法应该控制片段
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener()
@Override
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments)
switch (destination.getId())
case R.id.nav_home:
Toast.makeText(MainActivity.this,
"Home clicked",Toast.LENGTH_LONG).show();
break;
case R.id.nav_Accessory:
Toast.makeText(MainActivity.this,
"Accessory clicked",Toast.LENGTH_LONG).show();
break;
case R.id.nav_Arcade:
Toast.makeText(MainActivity.this,
"Arcade clicked",Toast.LENGTH_LONG).show();
break;
);
PostAdapter 类
public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private Context context;
private List<Item> items;
private static final int CARD = 0;
private static final int CARD_MAGAZINE = 1;
private static final int TITLE = 2;
private static final int GRID = 3;
private static final int SDK_VERSION = Build.VERSION.SDK_INT;
public static final String TAG = "POST ADAPTER";
private int viewType;
public PostAdapter(Context context, List<Item> items)
this.context = context;
this.items = items;
public void setViewType(int viewType)
this.viewType = viewType;
notifyDataSetChanged();
public int getViewType()
return this.viewType;
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
LayoutInflater inflater = LayoutInflater.from(context);
View view;
if (this.viewType == CARD)
view = inflater.inflate(R.layout.card, parent, false);
return new CardViewHolder(view);
else if (this.viewType == CARD_MAGAZINE)
view = inflater.inflate(R.layout.card_magazine, parent, false);
return new CardMagazineViewHolder(view);
else if (this.viewType == TITLE)
if(SDK_VERSION < Build.VERSION_CODES.LOLLIPOP)
view = inflater.inflate(R.layout.title_layout_v15,parent,false);
else
view = inflater.inflate(R.layout.title_layout, parent, false);
return new TitleViewHolder(view);
else
if(SDK_VERSION < Build.VERSION_CODES.LOLLIPOP)
view = inflater.inflate(R.layout.grid_layout_v15,parent,false);
else
view = inflater.inflate(R.layout.grid_layout, parent, false);
return new GridViewHolder(view);
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position)
int itemType = getViewType();
Item item = items.get(holder.getAdapterPosition());
final Document document = Jsoup.parse(item.getContent());
final Elements elements = document.select("img");
// Log.e("IMAGE", document.getAllElements().select("img").get(0).attr("src"));
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat
("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
Intent intent = new Intent(context, DetailsActivity.class);
switch (itemType)
case CARD:
if (holder instanceof CardViewHolder)
CardViewHolder cardViewHolder = (CardViewHolder) holder;
cardViewHolder.postTitle.setText(item.getTitle());
try
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(cardViewHolder.postImage);
catch (IndexOutOfBoundsException e)
cardViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
cardViewHolder.postDescription.setText(document.text());
try
date = format.parse(items.get(position).getPublished());
catch (ParseException e)
e.printStackTrace();
PrettyTime prettyTime = new PrettyTime();
cardViewHolder.postDate.setText(prettyTime.format(date));
cardViewHolder.itemView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility = 0;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video"))
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
if (youtubeThumbnailImageSrc.isEmpty())
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
else
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
);
break;
case CARD_MAGAZINE:
if (holder instanceof CardMagazineViewHolder)
CardMagazineViewHolder cardMagazineViewHolder = (CardMagazineViewHolder) holder;
cardMagazineViewHolder.postTitle.setText(item.getTitle());
try
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(cardMagazineViewHolder.postImage);
catch (IndexOutOfBoundsException e)
cardMagazineViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
try
date = format.parse(items.get(position).getPublished());
catch (ParseException e)
e.printStackTrace();
PrettyTime prettyTime = new PrettyTime();
cardMagazineViewHolder.postDate.setText(prettyTime.format(date));
cardMagazineViewHolder.itemView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility = 0;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video"))
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
if (youtubeThumbnailImageSrc.isEmpty())
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
else
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
);
break;
case TITLE:
if (holder instanceof TitleViewHolder)
TitleViewHolder titleViewHolder = (TitleViewHolder) holder;
titleViewHolder.postTitle.setText(item.getTitle());
Log.d("TITLE", "title layout called");
try
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(titleViewHolder.postImage);
catch (IndexOutOfBoundsException e)
titleViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
if(position == getItemCount() -1)
if(context instanceof MainActivity)
// ((MainActivity)context).getMainPagePosts();
titleViewHolder.itemView.setOnClickListener(view ->
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility = 0;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video"))
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
if (youtubeThumbnailImageSrc.isEmpty())
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
else
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
);
break;
case GRID:
if (holder instanceof GridViewHolder)
GridViewHolder gridViewHolder = (GridViewHolder) holder;
gridViewHolder.postTitle.setText(item.getTitle());
try
Log.e("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(gridViewHolder.postImage);
catch (IndexOutOfBoundsException e)
gridViewHolder.postImage.setImageResource(R.mipmap.ic_launcher);
Log.e(TAG,e.toString());
if(position == getItemCount() -1)
if(context instanceof MainActivity)
// ((MainActivity)context).getMainPagePosts();
gridViewHolder.itemView.setOnClickListener(view ->
intent.putExtra("url", item.getUrl());
intent.putExtra("title", item.getTitle());
intent.putExtra("content", item.getContent());
int youtubeThumbnailImagesetVisibility;
Element element = document.body();
String youtubeThumbnailImageSrc = "";
String youTubeLink = "";
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video"))
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
if (youtubeThumbnailImageSrc.isEmpty())
youtubeThumbnailImagesetVisibility = 8;
intent.putExtra("youtubeThumbnailImagesetVisibility",
youtubeThumbnailImagesetVisibility);
else
intent.putExtra("youtubeThumbnailImageSrc", youtubeThumbnailImageSrc);
intent.putExtra("youTubeLink", youTubeLink);
// String imageSrc = elements.get(0).attr("src");
// intent.putExtra("blogImage",imageSrc);
view.getContext().startActivity(intent);
);
@Override
public int getItemCount()
return items.size();
@Override
public long getItemId(int position)
return position;
public class CardViewHolder extends RecyclerView.ViewHolder
ImageView postImage;
TextView postTitle,postDescription, postDate;
private CardViewHolder(View itemView)
super(itemView);
postImage = itemView.findViewById(R.id.postImage);
postTitle = itemView.findViewById(R.id.postTitle);
postDescription = itemView.findViewById(R.id.postDescription);
postDate = itemView.findViewById(R.id.postDate);
public class CardMagazineViewHolder extends RecyclerView.ViewHolder
ImageView postImage;
TextView postTitle, postDate;
private CardMagazineViewHolder(View itemView)
super(itemView);
postImage = itemView.findViewById(R.id.postImage);
postTitle = itemView.findViewById(R.id.postTitle);
postDate = itemView.findViewById(R.id.postDate);
public class TitleViewHolder extends RecyclerView.ViewHolder
TextView postTitle;
MyImageview postImage;
private TitleViewHolder(@NonNull View itemView)
super(itemView);
postTitle = itemView.findViewById(R.id.postTitle);
postImage = itemView.findViewById(R.id.postImage);
public class GridViewHolder extends RecyclerView.ViewHolder
TextView postTitle;
MyImageview postImage;
private GridViewHolder(@NonNull View itemView)
super(itemView);
postTitle = itemView.findViewById(R.id.postTitle);
postImage = itemView.findViewById(R.id.postImage);
【问题讨论】:
【参考方案1】:我不认为有一种简单的方法可以做到这一点,但在我的情况下,我使用接口绑定视图这里是我如何从活动访问 TextView 的示例:
这是活动:
public class MainActivity4 extends AppCompatActivity implements OnFragmentViewCreated
private TextView fragmentTextView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
getSupportFragmentManager().beginTransaction().add(R.id.fragment, new TestFragment()).commit();
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater inflater = new MenuInflater(this);
inflater.inflate(R.menu.test, menu);
return super.onCreateOptionsMenu(menu);
/**
* this method called each time a fragment Created. you can initialize the view on in
*
* @param fragment the instance of the fragment that called it
* @param view the view that has bonded
*/
@Override
public void onBindView(Fragment fragment, View view)
if (fragment instanceof TestFragment)
// here i know that i sent a TextView
fragmentTextView = ((TextView) view);
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item)
if (fragmentTextView != null)
switch (item.getItemId())
case R.id.home:
fragmentTextView.setText("this is only a Test: Option Selected 0");
break;
case R.id.nav_bus:
fragmentTextView.setText("this is only a Test: Option Selected 1");
break;
return super.onOptionsItemSelected(item);
这是片段
public class TestFragment extends Fragment
private TextView textView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
View v = inflater.inflate(R.layout.fragment_first, container, false);
textView = v.findViewById(R.id.textview_first);
return v;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
// initialize the interface for each fragment
OnFragmentViewCreated viewFragmentCreated = (OnFragmentViewCreated) requireActivity();
// call the method in the activity
viewFragmentCreated.onBindView(this, textView);
最后这是界面
public interface OnFragmentViewCreated
void onBindView(Fragment fragment, View view);
更新
对于@Dr Mido的例子,如果你想访问RecyclerView和Apdapter你必须改变接口如下
public interface OnFragmentViewCreated
void onBindView(Fragment fragment, RecyclerView view, RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter);
并在 onViewCreated()
的 Fragment 中添加它 @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
/*
rest of your code here
*/
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
// initialize the interface
OnFragmentViewCreated viewFragmentCreated = (OnFragmentViewCreated) requireActivity();
// call the method in the activity
viewFragmentCreated.onBindView(this, recyclerView, userAdapter);
当您在 Activity 中实现此接口时,您必须初始化视图以便在 onOptionsItemSelected 方法中使用它们:
/**
* this method called each time a fragment Created. you can initialize the recyclerView on in
*
* @param fragment the instance of the fragment that called it
* @param recyclerView your recycler recyclerView in the fragment
* @param adapter your adapter
*/
@Override
public void onBindView(Fragment fragment, RecyclerView recyclerView, RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter)
if (fragment instanceof TestFragment)
this.recyclerView = recyclerView;
//replace the UserAdapter by your Adapter
this.adapter = (UserAdapter) adapter;
就像您在问题中所做的那样,您可以在 onOptionsItemSelected 中使用它们,就像下面的代码一样:
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item)
if (recyclerView != null && adapter != null)
switch (item.getItemId())
case R.id.home:
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
break;
case R.id.nav_bus:
break;
return super.onOptionsItemSelected(item);
这里一切正常
【讨论】:
AS 不会接受此接口的覆盖,而且当我运行应用程序时,它需要我提供它,我认为这是 AS 中的错误,并且我认为适配器无法转换为查看 不只是我给你一个例子,如果你想访问你需要更改接口的签名,如 voidonBindView(Recyclerview recyclerview, yourAdapter adapter, Fragment fragment)
如果我没听错,你的意思是 AS 的 Android Studio,好吧,也许你误用了界面
yes 作为Android studio的快捷方式,当然我没有错过界面,我尝试在同一个类和单独的文件中创建它,我会再试一次
我编辑了我的问题并添加了适配器类的完整代码以上是关于如何访问活动内部/从活动中的片段视图组件的主要内容,如果未能解决你的问题,请参考以下文章