![](/img/trans.png)
[英]Is it possible to disable access to fragment's layout(views) from parent activity?
[英]How to access Fragment's child views inside fragment's parent Activity?
我有一個支持的片段活動,它將加載差異片段。 該片段具有一定textView
與id = "score"
,我想它的手柄,但findViewById
為得分的textView
返回null。 為什么這樣?
textView 放置在片段中
public class MyActivity extends extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks{
private TextView scoreBoardTextView = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
scoreBoardTextView = (TextView) findViewById(R.id.score); //this returns null
}
@Override
public void onNavigationDrawerItemSelected(int position) {
//set fragment
}
}
直接訪問片段之外的片段視圖不是一個好主意。 您應該使用片段回調接口來處理這種情況並避免錯誤。 以下方式有效,但不建議這樣做,因為這不是一個好的做法。
Activity
訪問Fragment
的TextView
,那么你應該在你的Fragment
類中定義一個方法,如下所示:
public class MyFragment extends Fragment { TextView mTextView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.activity_main, container, false); mTextView = (TextView) view.findViewById(R.id.textView1); return view; } public void setTextViewText(String value){ mTextView.setText(value); } }
現在你可以像這樣在你的Activity
使用它:
public class MyFragment extends Fragment {
TextView mTextView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, container, false);
mTextView = (TextView) view.findViewById(R.id.textView1);
return view;
}
public void setTextViewText(String value){
mTextView.setText(value);
}
}
這里 myFragment 是MyFragment
類型。
如果你想訪問整個TextView
那么你可以在MyFragment.java
定義一個這樣的方法:
public TextView getTextView1(){ return mTextView; }
通過這種方式,您可以訪問TextView
本身。
希望這可以幫助。 :)
可以通過以下方式:
在 Fragment 中保持對膨脹視圖的引用,如下所示:
public class MyFragment extends SherlockFragment{
MainMenuActivity activity;
public View view;
public MyFragment(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if ( getActivity() instanceof MainMenuActivity){
activity = (MainMenuActivity) getActivity();
}
view = inflater.inflate(R.layout.aboutus, container, false);
return view;
}
}
在Activity中創建一個函數,像這樣:
public class MainMenuActivity extends SherlockFragmentActivity {
SherlockFragment fragment = null;
public void switchContent(SherlockFragment fragment) {
this.fragment = fragment;
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.mainmenu, fragment)
.commit();
invalidateOptionsMenu();
}
其目的是保持對當前片段的引用。 每當你想切換片段時,你調用上面的函數,像這樣(來自片段):
activity.switchContent( new MyFragment_2());
現在你有當前的片段參考。 所以你可以像這樣直接在 Activity 中訪問 Fragment 的視圖: this.fragment.view
您無需參考Fragment視圖即可在Activity 中獲取其組件。 因為您可以直接訪問父Activity 中Fragment 的布局組件。
簡單地你可以通過這個訪問任何組件
findViewById(R.id.child_of_fragment_layout);
您可以使用 Fragment 類的 getView 方法訪問。
例如,您的 MyFragment 中有一個 TextView,ID 為“text_view”
在您的活動中制作您的片段:
MyFragment myFragment = new MyFragment();
當您需要孩子時,只需調用 getView,然后找到您的 childView。
View view = myFragment.getView();
if (view !=null) {
view.findViewById(R.id.text_view).setText("Child Accessed :D");
}
注意:如果您想要片段的根視圖,則myFragment.getView();
簡直夠了。
為了訪問 TextView 或 Button 或片段中的任何內容,您需要執行以下操作:
public class BlankFragment extends Fragment {
public View view;
public TextView textView;
public Button button;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view =inflater.inflate(R.layout.fragment_blank, container, false);
textView = (TextView)view.getRootView().findViewById(R.id.textView_fragment1);
return view;
}
public void changeTextOfFragment(String text){
textView.setText(text);
view.setBackgroundResource(R.color.colorPrimaryDark);
}
一旦在 MainActivity 或任何其他要從 Fragment 訪問 TextView 的地方完成此操作,您應該確保在 OnCreate() 方法中以其他方式設置片段,它很可能會拋出 nullPointer。 因此,您要更改 TextView 的活動應如下所示:
public class MainActivity extends AppCompatActivity {
private Button button1;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
BlankFragment blankFragment = new BlankFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button)findViewById(R.id.button1);
changeFragment();
fragmentManager = getFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment1,blankFragment);
fragmentTransaction.commit();
}
private void changeFragment(){
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
blankFragment.changeTextOfFragment("Enter here the text which you want to be displayed on your Updated Fragment");
}
});
}
希望這可以幫助 :)
只需放入片段而不是放入活動:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_new_work_order,
container, false);
TextView scoreBoardTextView = (TextView) rootView.findViewById(R.id.score);
return rootView;
}
只這樣做:
((Your_Activity) this.getActivity()).YouyActivityElements;
如果您的 TextView 放置在 Fragment 中,那么您無法訪問Fragment Parent Activity 中的TextView,您可以設置 Fragment 和 Activity 之間的互通接口,並在單擊 TextView 或任何其他您想要發生的事情時發送數據
您無法訪問 Parent Activity
Fragment
元素,但您可以通過以下方式將值傳遞給您的Fragment
。
在onNavigationDrawerItemSelected
的方法MyActivity
做到以下幾點
int myScore = 100;
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager
.beginTransaction()
.replace(R.id.container,
MyFragment.newInstance(myScore)).commit();
}
並在MyFragment
類中創建一個名為newInstance
的方法,如下所示
private static final String SCORE = "score";
public static MyFragment newInstance(int score) {
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putInt(SCORE, score);
fragment.setArguments(args);
return fragment;
}
在MyFragment
的onCreateView()
方法中
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
TextView textView = (TextView) rootView
.findViewById(R.id.score);
textView.setText(Integer.toString(getArguments().getInt(
SCORE)));
return rootView;
}
就這些,希望對你有幫助。 如果沒有,請告訴我。
得分textView 在fragment 的布局中,不在MyActivity 的布局中,即R.layout.activity_home。 因此,一旦您擴充了相應的布局文件,您就可以在該片段中找到分數文本視圖。
它返回null
因為TextView
是Fragment
一個元素,而不是Activity
。
請注意,使用Fragment
的想法是在Fragment
內封裝一個模塊,這意味着Activity
不應直接訪問其屬性。 考慮將您的邏輯移到Fragment
獲取TextView
引用的位置
只需在片段中將 TextView 聲明為 public,在片段的 onCreateView() 中通過 findViewById() 對其進行初始化。 現在通過使用您在活動中添加的 Fragment 對象,您可以訪問 TextView。
您需要從片段視圖中調用方法 findViewById。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
scoreBoardTextView = (TextView) mNavigationDrawerFragment.getView().findViewById(R.id.score);
}
這種方式對我有用。
我建議您將 textview 作為活動布局的一部分。 或者,您可以將 textview 作為單獨的片段。 在這里看看我的問題。 它與您的相似,但方向相反。 這是我在項目中使用的代碼的精簡版本。 解釋在代碼中。
活動課
public class MainActivity extends ActionBarActivity {
PlaceFragment fragment;
TextView fragmentsTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Bundle bundle = new Bundle();
bundle.putString("score", "1000");
fragment = PlaceFragment.newInstance(bundle);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
// method 1
// fragment is added some ways to access views
// get the reference of fragment's textview
if (fragment.getTextView() != null) {
fragmentsTextView = fragment.getTextView();
}
// method 2
// using static method dont use in production code
// PlaceFragment.textViewInFragment.setText("2000");
// method 3
// let the fragment handle update its own text this is the recommended
// way wait until fragment transaction is complete before calling
//fragment.updateText("2000");
}
}
片段類:
public class PlaceFragment extends Fragment {
public TextView textViewInFragment;// to access via object.field same to
// string.length
// public static TextView textViewInFragment;//to access via
// PlaceFragment.textView dont try this in production code
public PlaceFragment() {
}
public static PlaceFragment newInstance(Bundle bundle) {
PlaceFragment fragment = new PlaceFragment();
fragment.setArguments(bundle);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment_place, container, false);
textViewInFragment = (TextView) view
.findViewById(R.id.textViewInFragment);
return view;
}
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
if (getArguments() != null) {
textViewInFragment.setText(getArguments().getString("score"));
}
}
public TextView getTextView() {
if (textViewInFragment != null) {
return textViewInFragment;// returns instance of inflated textview
}
return null;// return null and check null
}
public void updateText(String text) {
textViewInFragment.setText(text);// this is recommended way to alter
// view property of fragment in
// activity
}
}
從活動到片段的通信是直截了當的。 這是因為活動包含片段。 保留片段對象並通過 setter 和 getter 或其中的公共字段訪問其屬性。 但是從片段到活動的通信需要一個接口。
為什么不直接從 FragmentPagerAdapter 訪問它,
SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
subAccountFragment.requestConnectPressed(view);
這是完整的例子:
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Locale;
public class TabsActivity extends ActionBarActivity implements ActionBar.TabListener {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
// Set up the action bar.
final ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
ActionBar.Tab tab = actionBar.newTab();
View tabView = this.getLayoutInflater().inflate(R.layout.activity_tab, null);
ImageView icon = (ImageView) tabView.findViewById(R.id.tab_icon);
icon.setImageDrawable(getResources().getDrawable(mSectionsPagerAdapter.getPageIcon(i)));
TextView title = (TextView) tabView.findViewById(R.id.tab_title);
title.setText(mSectionsPagerAdapter.getPageTitle(i));
tab.setCustomView(tabView);
tab.setTabListener(this);
actionBar.addTab(tab);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_tabs, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_logout) {
finish();
gotoLogin();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public ProfileFragment profileFragment;
public SubAccountFragment subAccountFragment;
public ChatFragment chatFragment;
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
profileFragment = new ProfileFragment();
subAccountFragment = new SubAccountFragment();
chatFragment = new ChatFragment();
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return profileFragment;
case 1:
return subAccountFragment;
case 2:
return chatFragment;
}
return null;
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
public int getPageIcon(int position) {
switch (position) {
case 0:
return R.drawable.tab_icon_0;
case 1:
return R.drawable.tab_icon_1;
case 2:
return R.drawable.tab_icon_2;
}
return 0;
}
}
public void gotoLogin() {
Intent intent = new Intent(this, LoginActivity.class);
this.startActivity(intent);
}
public void requestConnectPressed(View view){
SubAccountFragment subAccountFragment = (SubAccountFragment) mSectionsPagerAdapter.getItem(1);
subAccountFragment.requestConnectPressed(view);
}
}
如果視圖已經在屏幕上膨脹(例如可見),那么您可以像往常一樣在活動中使用 findViewById(R.id.yourTextView) ,如果未找到視圖,它將返回文本視圖的句柄或 null。
我只是使用方法從父活動訪問片段視圖,因為我們創建了一個新的片段類對象來插入片段。 所以我喜歡這個。
class BrowserFragment : Fragment(), Serializable {
private lateinit var webView: NestedScrollWebView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
webView = view.findViewById(R.id.web_view)
}
fun getWebView(): WebView {
return webView
}
}
在MainActivity
val browserFragment = BrowserFragment()
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.browser_fragment_placeholder, browserFragment)
fragmentTransaction.commit()
val webView = browserFragment.getWebView()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.