#java #android #android-fragments #android-viewpager
#java #Android #android-фрагменты #android-viewpager
Вопрос:
Я вызываю ViewPager (фрагмент C) из ListView (фрагмент A). Но это работает только один раз. Если я вернусь к своему списку и выберу другой элемент, он не переместится в listview. Он просто показывает пустой макет фрагмента c.
Ниже приведен код для фрагмента A:
public class FragmentA extends Fragment implements AdapterView.OnItemClickListener{
ListView list;
Communicator communicator;
ArrayList<Book> book_a;
ArrayList<String> book_titles;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_a,container,false);
savedInstanceState = getArguments();
if (getArguments() != null) {
// savedInstanceState = getArguments();
book_a = (ArrayList<Book>) getArguments().getSerializable("bookarray");
book_titles = getList(book_a);
//Log.d("Frag_a:Title",book_a.get(5).getTitle());
list= (ListView) view.findViewById(R.id.listview);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,book_titles);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
return view;
}
public ArrayList<String> getList(ArrayList<Book> book2){
ArrayList<String> list_titles = new ArrayList<String>();
int size = book2.size();
for(int i=0;i<size;i ){
Book object;
object = book2.get(i);
list_titles.add(object.title);
}
return list_titles;
}
public void setCommunicator(Communicator communicator)
{
this.communicator = communicator;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
communicator.respond(position);
}
public interface Communicator{
public void respond(int index);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof Communicator){
communicator = (Communicator) context;
} else {
throw new RuntimeException(context.toString() "must implement Communicator");
}
}
@Override
public void onDetach() {
super.onDetach();
communicator = null;
}
}
Ниже приведен код для MainActivity:
public class MainActivity extends AppCompatActivity implements FragmentA.Communicator{
FragmentB f2;
ArrayList<Book> b = new ArrayList<Book>();
FragmentManager manager;
static int flag = 0;
static String search="great";
SearchView sv ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sv = (SearchView) findViewById(R.id.searchView);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
flag = 1;
search = query;
getBooks();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
getBooks();
return false;
}
});
getBooks();
/*
manager = getSupportFragmentManager();
f1 = (FragmentA) manager.findFragmentById(R.id.fragment);
f1.setCommunicator(this);*/
}
@Override
public void respond(int index) {
f2 = (FragmentB) manager.findFragmentById(R.id.fragment2);
if(f2!=null amp;amp; f2.isVisible())
{
f2.changeData(index);
}
else
{
Bundle bundle = new Bundle();
bundle.putInt("index", index);
bundle.putSerializable("bookarray",(ArrayList<Book>)b);
Fragment newFragment = new FragmentC();
newFragment.setArguments(bundle);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
public void afterGetBooks(ArrayList<Book> bks) {
for (Book h : bks) {
b.add(h);
}
manager = getSupportFragmentManager();
Bundle args = new Bundle();
args.putSerializable("bookarray",(ArrayList<Book>)bks);
FragmentA f1 = new FragmentA();
f1.setArguments(args);
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment,f1);
transaction.addToBackStack(null);
transaction.commit();
f1.setCommunicator(this);
}
private void getBooks(){
String url;
if(flag==0){
url = "https://kamorris.com/lab/audlib/booksearch.php/";}
else{
url = "https://kamorris.com/lab/audlib/booksearch.php?search=" search;
flag=0;
}
//ArrayList<Book> boo;
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://kamorris.com/lab/audlib/booksearch.php/").addConverterFactory(GsonConverterFactory.create()).build();
Book.API api = retrofit.create(Book.API.class);
Call<ArrayList<Book>> call = api.getBooks(url);
call.enqueue(new Callback<ArrayList<Book>>() {
@Override
public void onResponse(Call<ArrayList<Book>> call, Response<ArrayList<Book>> response) {
ArrayList<Book> Books = response.body();
for(Book h: Books){
Log.d("Retro-Title",h.getTitle());
//b.add(h);
}
afterGetBooks(Books);
}
@Override
public void onFailure(Call<ArrayList<Book>> call, Throwable t) {
Toast.makeText(getApplicationContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
Ниже приведен код для фрагмента C:
public class FragmentC extends Fragment {
ViewPager vp;
static int list_pos;
FragmentPagerAdapter adapterViewPager;
public static ArrayList<Book> book_c;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_c,container,false);
if(getArguments()!= null){
book_c = (ArrayList<Book>) getArguments().getSerializable("bookarray");
list_pos = getArguments().getInt("index");
}
vp = (ViewPager) view.findViewById(R.id.viewpager);
adapterViewPager = new MyPagerAdapter(getFragmentManager());
vp.setAdapter(adapterViewPager);
return view;
}
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 11;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
@Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (list_pos) {
case 0: // Fragment # 0 - This will show FirstFragment
list_pos = position;
return FragmentB.newInstance(book_c,0);
case 1: // Fragment # 0 - This will show FirstFragment different title
list_pos = position;
return FragmentB.newInstance(book_c,1);
case 2: // Fragment # 1 - This will show SecondFragment
list_pos = position;
return FragmentB.newInstance(book_c,2);
case 3: list_pos = position;
return FragmentB.newInstance(book_c,3);
case 4:list_pos = position;
return FragmentB.newInstance(book_c,4);
case 5:list_pos = position;
return FragmentB.newInstance(book_c,5);
case 6:list_pos = position;
return FragmentB.newInstance(book_c,6);
case 7:list_pos = position;
return FragmentB.newInstance(book_c,7);
case 8:list_pos = position;
return FragmentB.newInstance(book_c,8);
case 9:list_pos = position;
return FragmentB.newInstance(book_c,9);
default:
return null;
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
return "Page " position;
}
}
}
Также есть ли способ, с помощью которого я могу запустить свой viewpager из описания выбранного мной списка.
Также фрагмент B — это просто держатель текстового представления.
Я попытался просмотреть поток управления с помощью отладчика. Но когда я пытаюсь сделать это таким образом, эти строки во фрагменте C не работают..
{
book_c = (ArrayList<Book>) getArguments().getSerializable("bookarray");
list_pos = getArguments().getInt("index");
}
vp = (ViewPager) view.findViewById(R.id.viewpager);
adapterViewPager = new MyPagerAdapter(getFragmentManager());
vp.setAdapter(adapterViewPager);
Ответ №1:
Ваш фрагмент не был уничтожен, и поэтому, когда он возвращается, onCreateView не вызывается. Вместо этого переопределите setUserVisibleHint .
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// This is true when your fragment is visible, write code to populate view here
} else {
// This is true when your fragment is hidden.
}
}
Комментарии:
1. Извините, но не могли бы вы сказать мне, что я должен делать после добавления этого кода во фрагмент C… Вы вводите // Выполняете часть своей работы, но я не могу понять, что мне нужно там делать..
2. Дайте мне знать, если это работает для вас или вам нужно больше разъяснений.
3. извините, я только начинаю с основ …. но нравится ли мне размещать эту часть кода в части if — «vp = (ViewPager) view.findViewById(R.id.viewpager); adapterViewPager = новый MyPagerAdapter(getFragmentManager()); vp.setAdapter(adapterViewPager);» и оставить часть else пустой?
4. Вы бы поместили это туда: if(getArguments()!= null){ book_c = (ArrayList<Book>) getArguments().getSerializable(«bookarray»); list_pos = getArguments().getInt(«index»); } vp = (ViewPager) view.findViewById(R.id.viewpager); adapterViewPager = новый MyPagerAdapter(getFragmentManager()); vp.setAdapter(adapterViewPager);
5. я попробовал этот код … но когда я пытаюсь запустить отладчик, элемент управления не перемещается в setUserVisibleHint в all….it выполняется только в режиме onCreate
Ответ №2:
Решение, которое я нашел, — изменить диспетчер фрагментов
adapterViewPager = new MyPagerAdapter(getFragmentManager());
Для
adapterViewPager = new MyPagerAdapter(getChildFragmentManager());