2016-02-02 3 views
1

Конечная цель состоит в том, чтобы щелкнуть по списку, хранящемуся в одном фрагменте, открыть другой фрагмент, который имеет вложенные фрагменты вида AnswerFragment, здесь вложенные фрагменты должны состоять из двух фрагментов, текст из списка, а нижняя половина - ответ. Прямо сейчас мне удалось снять бит связи с передачей текста вопроса из списка на один фрагмент вопроса (который должен храниться в верхней половине фрагмента ответа). Однако он раздувает единый макет вопроса по фрагменту ответа подобный SingleQuestionFragment .Вложенные фрагменты метаданных null

public class MainActivity extends AppCompatActivity implements AllQsFragment.Communicator { 

private DrawerLayout mDrawer; 
private Toolbar toolbar; 

private NavigationView mNVDrawer; 
private ActionBarDrawerToggle drawerToggle; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //Set a Toolbar to replace the ActionBar. 
    toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 


    mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
    drawerToggle = setupDrawerToggle(); 

    mDrawer.setDrawerListener(drawerToggle); 

    //Find our drawer view 
    mNVDrawer = (NavigationView) findViewById(R.id.nvView); 
    //Setup drawer view 
    setupDrawerContent(mNVDrawer); 

} 

private ActionBarDrawerToggle setupDrawerToggle() { 
    return new ActionBarDrawerToggle(this, mDrawer, toolbar, R.string.drawer_open, R.string.drawer_close); 
} 

private void setupDrawerContent(NavigationView navigationView) { 
    navigationView.setNavigationItemSelectedListener(
      new NavigationView.OnNavigationItemSelectedListener() { 
       @Override 
       public boolean onNavigationItemSelected(MenuItem menuItem) { 
        selectDrawerItem(menuItem); 
        return true; 
       } 
      }); 
} 

public void selectDrawerItem(MenuItem menuItem) { 
    //Creat a new fragment and specify the planet to show based on 
    //position 
    Fragment fragment = null; 

    Class fragmentClass; 
    switch (menuItem.getItemId()) { 
     case R.id.nav_first_fragment: 
      fragmentClass = AllQsFragment.class; 
      break; 
     default: 
      fragmentClass = AllQsFragment.class; 
    } 

    try { 
     fragment = (Fragment) fragmentClass.newInstance(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    //Insert the fragment by replacing any existing fragment 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment).addToBackStack("addedToBackStack").commit(); 

    //Highlight the selected item, update the title, and close the drawer 
    menuItem.setChecked(true); 
    setTitle(menuItem.getTitle()); 
    mDrawer.closeDrawers(); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    //The action bar home/up action should open or close the drawer 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      mDrawer.openDrawer(GravityCompat.START); 
      return true; 
    } 

    if (drawerToggle.onOptionsItemSelected(item)) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

@Override 
protected void onPostCreate(Bundle savedInstanceState) { 
    super.onPostCreate(savedInstanceState); 
    //Sync the toggle state after onRestoreInstanceState has occurred 
    drawerToggle.syncState(); 
} 

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    //Pass any configuration change to the drawer toggles 
} 


@Override 
public void sendText(String data) { 
    SingleQuestionFragment questionFragment = (SingleQuestionFragment) getSupportFragmentManager().findFragmentByTag("fragmentQ"); 
    if (questionFragment != null) { 
     questionFragment.changeText(data); 
    } else { 
     SingleQuestionFragment fragment = new SingleQuestionFragment(); 
     Bundle args = new Bundle(); 
     args.putString("text", data); 
     fragment.setArguments(args); 
     getSupportFragmentManager().beginTransaction() 
       .replace(R.id.flContent, fragment) 
       .addToBackStack(null).commit(); 
     fragment.sentText(); 
    } 
} 

} 

fragment_answer

<FrameLayout 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" 
tools:context="com.example.victor.nattest5.AnswerFragment"> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 


    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1" 
     android:id="@+id/q_fragment"> 

    </FrameLayout> 

    <FrameLayout 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1" 
     android:id="@+id/a_fragment"> 

    </FrameLayout> 

</LinearLayout> 

AnswerFragment

public class AnswerFragment extends Fragment { 

public AnswerFragment() { 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    insertNestedFragment(); 
    return inflater.inflate(R.layout.fragment_answer, container, false); 

} 

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
} 

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

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
} 

private void insertNestedFragment() { 
    Fragment childQFragment = new SingleQuestionFragment(); 
    FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); 
    transaction.add(R.id.q_fragment, childQFragment, 
        "fragmentQ").commit(); 

    Fragment childAFragment = new SingleAnswerFragment(); 
    FragmentTransaction transaction1 = getChildFragmentManager().beginTransaction(); 
    transaction1.add(R.id.a_fragment, childAFragment, "fragmentA").commit(); 
} 

public static final AnswerFragment newInstance() { 
    AnswerFragment frag = new AnswerFragment(); 
    return frag; 
} 
} 

SingleQuestionFragment

public class SingleQuestionFragment extends Fragment { 
TextView questionTxt; 
String stringtext; 

public SingleQuestionFragment() { 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View v = inflater.inflate(R.layout.fragment_single_question, container, false); 
    questionTxt = (TextView) v.findViewById(R.id.textView_q); 
    return v; 
} 

public static final SingleQuestionFragment newInstance() { 
    SingleQuestionFragment frag = new SingleQuestionFragment(); 
    return frag; 
} 

public void changeText(String data) { 
    questionTxt.setText(data); 
} 

public void sentText() { 
    new BackGroundTask().execute(); 
} 

private class BackGroundTask extends AsyncTask<String, String, String> { 

    @Override 
    protected String doInBackground(String... strings) { 
     Bundle b = getArguments(); 
     stringtext = b.getString("text"); 
     return null; 
    } 

    protected void onPostExecute(String result){ 
     changeText(stringtext); 
    } 
} 

} 

Когда я запускаю это с помощью отладчика, приложение запускается без сбоев. Тем не менее, он показывает, что эта строка равна null -> SingleQuestionFragment questionFragment = (SingleQuestionFragment) getSupportFragmentManager(). FindFragmentByTag ("fragmentQ");

Я знаю, что означает нуль, я просто не понимаю, как исправить эту проблему. Где-то в моем коде, я думаю, что раздуваю дополнительный макет или, возможно, раздувая неправильный контейнер.

ответ

0

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

Вы не размещали код, который вызывает MainActivity.sendText(), или объясните причину его вызова.

Если я правильно понимаю ваше сообщение, в sendText(), вызов findFragmentByTag() возвращает null, и это ошибка. Ожидаете ли вы найти SingleQuestionFragment в AnswerFragment? Если это так, вы не найдете его, потому что вы просматриваете фрагменты, принадлежащие только менеджеру MainActivity. Поиск не включает фрагменты, которыми управляют дочерние фрагменты. Другими словами, поиск не рекурсивно ищет дерево фрагментов.

+0

Да, findFragmentByTag() возвращает значение null. Теперь я вижу ваш момент, это происходит потому, что я использую getSupportFragmentManager(), который указывает на контекст основной активности. По моему мнению, фрагмент взаимодействия фрагмента с фрагментом интерфейса должен был быть рассмотрен в основном действии, потому что здесь отображаются фрагменты. Как я вижу, getParentFragment() не работает в основном, есть ли у вас какие-либо предложения по этому поводу? Возможно, по возможности реализуя интерфейс строго по фрагментам. Также я вижу, что вам не нужен метод ASyncTask –

+0

Я мало знаю о вашем общем дизайне. Я думаю, что предлагаю управлять всеми фрагментами из основной деятельности и не использовать вложенные фрагменты. Помимо добавления и удаления фрагментов в макете, вы можете контролировать их видимость с помощью функции «FragmentTransaction».hide() 'и' FragmentTransaction.show() '. –

+0

Есть ли способ доступа к вложенным фрагментам через appcompatactivity? –

Смежные вопросы