5

Tôi có một Phân đoạn với phương thức setName() thay đổi văn bản EditText, bằng hàm setText.Truy cập phương thức Phân đoạn từ Hoạt động ViewPager

Cách tốt nhất để gọi phương thức đó từ hoạt động lưu trữ phân đoạn đó bằng phương tiện của ViewPager là gì?

Nói cách khác, làm cách nào tôi có thể truy cập các phương thức của Phân đoạn (ví dụ: thay đổi bố cục của phân đoạn đó) từ Hoạt động lưu trữ phân đoạn đó bằng phương tiện của một ViewPager?

Tôi yêu cầu điều này bởi vì tôi đã thử nhiều cách, nhưng luôn luôn có lỗi.

+0

Bạn có thể cố gắng tạo ra một biến thể hiện của các Fragment với 's Phương thức etName() 'trong lớp Activity của bạn. Gán biến cho Fragment khi bạn khởi tạo nó. sau đó bạn có thể gọi 'fragment.setName()' từ hoạt động của mình – Scott

+0

Tôi gặp sự cố này, nhưng gọi fragment.setName() qua tham chiếu được lưu trữ với nó, không phải là vấn đề. Vấn đề là từ đoạn, getActivity() trả về null để không thể truy cập các khung nhìn. Tuy nhiên, tôi có thể truy cập vào các khung nhìn từ hoạt động, và COULD mảnh đặt thông tin vào các khung nhìn thuộc về đoạn tại cấu hình. Nhưng sau đó, getActivity() trả về null và nó có thể là cái gì đó với viewPager kiểm soát ngữ cảnh sao cho getActivity thực sự không hợp lệ? Vì vậy, một trong những sẽ cần phải yêu cầu xem từ Viewpager? Tôi đang hỏi. – carl

Trả lời

3

Bạn có thể truy cập các phương thức công khai trong các đoạn được giữ bởi ViewPager. Bạn cần phải (1) lưu trữ một tham chiếu đến Fragment khi bạn tạo nó và thêm nó vào danh sách sẽ quay trở lại bộ điều hợp máy nhắn tin của bạn hoặc (2) bạn cần để có được một tham chiếu đến các mảnh từ bộ điều hợp máy nhắn tin chính nó. Ví dụ:

Fragment fragmentA = null; //instance variable 

fragmenA = new Fragment(); //whereever you instantiate your fragment 

Nếu phương pháp của bạn là

public void setName(String args){ 
    //do something 
} 

tất cả các bạn sẽ làm là gọi phương thức đó từ tham chiếu đến đoạn tổ chức bởi bạn ViewPager

fragmentA.setName(args); 

Bạn vượt qua bất cứ đối số bạn cần giống như gọi một phương pháp thông thường. Lưu ý CHỈ này hoạt động nếu bạn đang gọi một phương thức trong một đoạn từ nó có chứa ViewPager hoặc FragmentActivity. Nếu bạn muốn làm ngược lại, phân mảnh thành hoạt động, bạn cần sử dụng một lời nói đầu.

+0

Vâng, tôi biết điều này rồi. Nhưng điều gì sẽ xảy ra nếu tôi cố gắng tạo ra nó bằng cách sử dụng một cái gì đó giống như Frag1 fragment = (Frag1) mAppSectionsAdapter.getItem (0) ;? Làm thế nào tôi có nghĩa vụ phải sử dụng phương pháp sau đó mà không có ngoại lệ con trỏ null? – JZweige

+0

Nó giống như fragment.getView() luôn luôn là null! – JZweige

+0

Bạn muốn nhận tham chiếu từ bộ điều hợp của mình? Tôi không ở máy tính của mình nhưng tôi có thể đăng mã sau nếu đó là vấn đề. – Rarw

8

Tôi biết điều này hơi trễ một chút, nhưng tôi đã gặp phải vấn đề tương tự và có thể nó sẽ giúp người khác nếu bạn đã giải quyết nó.

Vấn đề đầu tiên tôi tìm thấy với ViewPager là gần như không thể có được một tham chiếu đến một đoạn. Các mảnh được tạo động trong getItem() và do đó bạn không thể đặt ID và chúng được tự động gắn thẻ lại bởi người giàu hơn, do đó bạn không thể tìm thấy nó theo thẻ. Có một số cách để làm điều đó, nhưng chúng đều là cách giải quyết. (Update data in ListFragment as part of ViewPager)

Cách tôi giải quyết nó đang sử dụng về cơ bản một cuộc gọi lại kép. Đoạn A có giao diện được thực hiện bởi Hoạt động chính, Hoạt động chính có giao diện được thực hiện bởi Phân đoạn B. Ví dụ: một nút clink trong Fragment Một chức năng gọi lại trong hoạt động chính được gọi, mà lần lượt gọi các cuộc gọi lại trong Fragment B. Nhìn vào mã dưới đây. Tôi hy vọng tôi đăng tất cả mọi thứ và nó sẽ giúp đỡ. btw, tôi đã chỉ thử điều này với một ViewPager, nhưng tôi cho rằng nó sẽ làm việc với bất kỳ loại giao tiếp Fragment nào.

chính Avtivity java:

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 

public class MainActivity extends FragmentActivity implements FragmentA.Caller { 

    SectionsPagerAdapter mSectionsPagerAdapter; 
    ViewPager mViewPager; 
    PassCallToB passOnToB = null; 
    FragmentManager myManager = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 
     mViewPager = (ViewPager) findViewById(R.id.pager); 
     mViewPager.setAdapter(mSectionsPagerAdapter); 
    } 

    public class SectionsPagerAdapter extends FragmentPagerAdapter { 

     public SectionsPagerAdapter(FragmentManager fm) { 
      super(fm); 
      MyManager = fm; 
     } 

     @Override 
     public Fragment getItem(int position) { 
      Fragment fragment = null; 
      if(position == 0) { 
       fragment = new FragmentA(); 
      } else if (position == 1) { 
       fragment = new FragmentB(); 
       passOnToB = (PassCallToB)fragment; 
      } 
      return fragment; 
     } 

     @Override 
     public int getCount() { 
      return 2; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      switch (position) { 
      case 0: 
       return "Frag A"; 
      case 1: 
       return "Frag B"; 
      } 
      return null; 
     } 

     public void setCallback() { 
      List<Fragment> frags = myManager.getFragments(); 
      for(Fragment fragment : frags) { 
       if(fragment instanceof FragmentB){ 
        passOnToB = (PassCallToB)fragment; 
       } 
      } 
     } 
    } 

    public interface PassCallToB { 
     public void passItOn(); 
    } 

    @Override 
    public void CallB() { 
     if(passOnToB instanceof Fragment) 
      passOnToB.passItOn(); 
     else { 
      mSectionsPagerAdapter.setCallback(); 
      passOnToB.passItOn(); 
     } 
    } 
} 

chính Hoạt động xml:

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/pager" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".MainActivity" > 

    <android.support.v4.view.PagerTitleStrip 
     android:id="@+id/pager_title_strip" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="top" 
     android:background="#33b5e5" 
     android:paddingBottom="4dp" 
     android:paddingTop="4dp" 
     android:textColor="#fff" /> 

</android.support.v4.view.ViewPager> 

Fragment Một java:

import android.app.Activity; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.Button; 

public class FragmentA extends Fragment { 

    Button btnCallB = null; 

    Caller listener = null; 

    public FragmentA() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) { 
     View rootView = inflater.inflate(R.layout.fragment_a, container, false); 

     btnCallB = (Button)rootView.findViewById(R.id.btnCallB); 
     btnCallB.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View view) { 
       listener.CallB(); 
      } 

     }); 

     return rootView; 
    } 

    public interface Caller { 
     public void CallB(); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     if (activity instanceof FragmentActivity) { 
      listener = (Caller) activity; 
     } else { 
      throw new ClassCastException(activity.toString() + " must implemenet listener"); 
     } 
    } 

    @Override 
     public void onDetach() { 
     super.onDetach(); 
     listener = null; 
     } 
} 

Fragment Một xml:

<RelativeLayout 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" > 


    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:text="This is Fragment A" /> 

    <Button 
     android:id="@+id/btnCallB" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_below="@+id/textView1" 
     android:text="Call Fragment B" /> 

</RelativeLayout> 

Fragment B Java:

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

public class FragmentB extends Fragment implements MainActivity.PassCallToB { 

    public FragmentB() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) { 
     View rootView = inflater.inflate(R.layout.fragment_b, container, false); 
     return rootView; 
    } 

    @Override 
    public void passItOn() { 
     Toast.makeText(getActivity(), "Hello from B", Toast.LENGTH_SHORT).show(); 

    } 
} 

Fragment B xml:

<RelativeLayout 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" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:text="This is Fragment B" /> 

</RelativeLayout> 
+0

Điều này không hoạt động khi bạn xoay. Bởi vì khi bạn xoay các hoạt động và các mảnh được tái tạo mà còn tái tạo SectionsPagerAdapter của bạn nhưng nó không bao giờ gọi getItem (Android tái tạo các mảnh mà không gọi getItem) có nghĩa là passOnToB vẫn là null. – rve

+0

Tôi đã chỉnh sửa mã của mình để mã sẽ hoạt động sau khi xoay màn hình. Bí quyết là thiết lập gọi lại không chỉ trong getItem(), mà còn bao gồm một phương thức tùy chỉnh trong bộ điều hợp máy nhắn tin sẽ tìm kiếm máng các mảnh và thiết lập gọi lại theo cách thủ công, khi tìm thấy đoạn chính xác. Bây giờ bạn chỉ phải kiểm tra xem cuộc gọi lại đã được đặt chưa và đặt nó nếu không có trong phương thức passOn. Tôi hy vọng điều này là hơi rõ ràng. – ckn

+0

Bất kỳ ý tưởng nào với tôi? http://stackoverflow.com/questions/39907625/why-is-accessing-textview-of-a-fragment-inside-activity-throwing-an-error – Si8

1

Fragment

private static FragmentName instance; 

public static synchronized FragmentName getInstance() 
{ 
    return instance; 
} 

@Override 
public void onCreate(@Nullable Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
instance=this; 
.... 
} 

public void methodName() 
{...} 

Hoạt động

FragmentName.getInstance().methodName(); 
Các vấn đề liên quan