Подтвердить что ты не робот

Как получить доступ к дочерним представлениям фрагмента внутри родительской части фрагмента?

У меня есть поддерживаемая функция фрагмента, которая будет загружать diff-фрагменты. У фрагмента есть textView с id = "score", и я хочу получить его дескриптор, но findViewById для score 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    
    }

}
4b9b3361

Ответ 1

Примечание:

Непосредственный доступ к представлениям фрагментов вне фрагмента - не очень хорошая идея. Вы должны использовать интерфейсы обратного вызова для обработки таких случаев и избегать ошибок. Следующий способ работает, но он не рекомендуется, так как это не очень хорошая практика.


Если вы хотите получить доступ к TextView из Fragment внутри родительского Activity, то вы должны определить метод внутри вашего класса 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 следующим образом:

myFragment.setTextViewText("foo");

здесь myFragment имеет тип MyFragment.

Если вы хотите получить доступ ко всему TextView, вы можете определить такой метод внутри MyFragment.java:

public TextView getTextView1(){
    return mTextView;
}

Таким образом вы можете получить доступ к самому TextView.

Надеюсь, что это поможет.:)

Ответ 2

Это возможно следующим образом:

Держите ссылку на раздутый вид в Фрагменте следующим образом:

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 следующим образом: this.fragment.view

Ответ 3

Вам не нужно ссылаться на представление Фрагмент, чтобы получить его компоненты в Деятельности. Поскольку вы можете напрямую обращаться к компонентам компоновки Фрагмент в родительском Деятельности.

Просто вы можете получить доступ к любому компоненту с помощью этого

findViewById(R.id.child_of_fragment_layout);  

Ответ 4

Вы можете получить доступ с помощью метода getView класса Fragment.

Например, у вас есть TextView в вашем MyFragment с идентификатором "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");
}

Ответ 5

Если ваш TextView размещен внутри фрагмента в этом случае, вы не можете получить доступ к TextView внутри вашего Фрагмент Родительского действия, вы можете установить интерфейс для взаимодействия между фрагментом и Activity и отправить данные, когда вы нажимаете TextView или любую другую вещь, которая вы хотите выполнить

Ответ 6

Только это:

((Your_Activity) this.getActivity()).YouyActivityElements;

Ответ 7

Просто поместите фрагмент вместо того, чтобы вводить в действие:

@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;
}

Ответ 8

Оценка textView находится в макете фрагмента, это не в макете MyActivity, т.е. R.layout.activity_home. Таким образом, вы можете найти текстовое представление в этом фрагменте после раздувания соответствующего файла макета.

Ответ 9

Он возвращает null, потому что TextView является элементом Fragment, а не Activity.

Обратите внимание, что идея использования Fragment заключается в инкапсуляции модуля внутри Fragment, что означает, что Activity не должен иметь прямого доступа к его свойствам. Подумайте о перемещении своей логики, когда вы получите ссылку TextView внутри Fragment

Ответ 10

Вы не можете получить доступ к элементу Fragment в Parent Activity, но вы можете передать значения в 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;
}

Это все, надеюсь, это вам поможет. Если нет, сообщите мне.

Ответ 11

Просто объявите TextView общедоступным в фрагменте, инициализируйте его findViewById() в фрагменте onCreateView(). Теперь, используя объект фрагмента, который вы добавили в действие, вы можете получить доступ к TextView.

Ответ 12

Вам нужно вызвать метод 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); 
}

Этот способ работает для меня.

Ответ 13

Я предлагаю вам сделать часть текста в вашем макете деятельности. В качестве альтернативы вы можете иметь текстовое представление как фрагмент separete. Посмотрите на мой question здесь. Он похож на ваш, но в обратном направлении. Здесь урезанная версия кода, которую я использовал в моем проекте. Объяснение приведено в коде.

Класс активности

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 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
}

}

Связь от активности к фрагменту является прямой. Это связано с тем, что активность содержит фрагмент. Храните объект фрагмента и получите доступ к его свойству через сеттеры и геттеры или публичные поля внутри него. Но для связи от фрагмента к активности требуется интерфейс.

Ответ 14

почему вы не обращаетесь к нему напрямую со своего 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);
    }
}

Ответ 15

Если представление уже завышено (например, видимо) на экране, вы можете просто использовать findViewById (R.id.yourTextView) в действии как обычно, и оно вернет дескриптор в текстовое представление или null, если представление было не найден.

Ответ 16

Чтобы получить доступ к 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 или любом другом, где вы хотите получить доступ к 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");

        }
    });
}

Надеюсь, что это поможет:)