Android 如何从当前ViewPager视图获取活动中的TextView

Android 如何从当前ViewPager视图获取活动中的TextView,android,nullpointerexception,android-viewpager,android-pageradapter,Android,Nullpointerexception,Android Viewpager,Android Pageradapter,我是Android开发新手。出于学习目的,我正在尝试创建一个类似旋转木马的东西。我是在ViewPager的帮助下完成的,然后使用PagerAdapter 我正在用JSON数据填充视图,它工作得很好。使用JSON加载和显示数据没有问题。问题是,当我试图在旋转木马活动中获取当前视图的数据时,会出现空指针异常 我想在我的viewpager中从当前视图复制/toast数据。为此,我尝试使用findViewById()获取当前视图,然后获取相关的textview,但它抛出空指针异常 我甚至尝试了findV

我是Android开发新手。出于学习目的,我正在尝试创建一个类似旋转木马的东西。我是在ViewPager的帮助下完成的,然后使用PagerAdapter

我正在用JSON数据填充视图,它工作得很好。使用JSON加载和显示数据没有问题。问题是,当我试图在旋转木马活动中获取当前视图的数据时,会出现空指针异常

我想在我的viewpager中从当前视图复制/toast数据。为此,我尝试使用
findViewById()
获取当前视图,然后获取相关的textview,但它抛出空指针异常

我甚至尝试了
findViewWithTag()
,但还是失败了。同样的一些研究告诉我,您必须在Adapter类中获得textview,并借助于扩展视图。不过我还没完全明白

下面给出的是我的CarouselAdapter.java文件:

public class CarouselAdapter extends PagerAdapter {
  Context context;
  public static LayoutInflater inflater=null;
  List<CarouselModel> result;

  public CarouselAdapter(CarouselPage carouselPage, List<CarouselModel> contentData) {
    result=contentData;
    context= carouselPage;
    inflater = ( LayoutInflater )context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  }

  public class SlideHolder {
    TextView description;
  }

  @Override
  public int getCount() {
    return this.result.size();
  }

  @Override
  public boolean isViewFromObject(View view, Object object) {
    return (view==(LinearLayout)object);
  }

  @Override
  public Object instantiateItem(ViewGroup container, int position) {
    SlideHolder holder = new SlideHolder();
    inflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.carousel_adapter,container,false);
    TextView tv = (TextView) view.findViewById(R.id.txtdescription);

    holder.description = tv;

    holder.description.setText(result.get(position).getDescription());

    container.addView(view);
    return view;
  }

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((LinearLayout)object);
  }
}
现在,在我的CarouselActivity.java中,我的工作如下:

protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.carousel_page);

  content = (ViewPager) findViewById(R.id.viewpager);

  cNextButton = (ImageButton) findViewById(R.id.carousel_next);
  cPrevButton = (ImageButton) findViewById(R.id.carousel_prev);

  // This button creates problem, and returns the null pointer error
  cCopyButton = (ImageButton) findViewById(R.id.carousel_copy);

  // This function loads up data from JSON to show in different views, and it works fine
  retrieveJSON();

  content.addOnPageChangeListener(viewListener);

  tv = content.findViewById(R.id.txtdescription);

  cNextButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
      content.setCurrentItem(cCurrentPage + 1);
    }
  });

  cPrevButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
      content.setCurrentItem(cCurrentPage - 1);
    }
  });

  cCopyButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
      Toast toast = Toast.makeText(getApplicationContext(), "Text is " + msg, Toast.LENGTH_LONG);
      toast.show();
    }
  });
}

private void retrieveJSON() {
  ....
}

ViewPager.OnPageChangeListener viewListener = new ViewPager.OnPageChangeListener() {
  @Override
  public void onPageScrolled(int i, float v, int j) {
  }

  @Override
  public void onPageSelected(int i) {
    cCurrentPage = i;

    //Have also tried this logic, but it returned null pointer error again
    //View view = content.getRootView();
    //tv = view.findViewById(R.id.txtdescription);

    if(i == 0) {
      cNextButton.setEnabled(true);
      cPrevButton.setEnabled(false);
    } else if(i == content.getChildCount()) {
      cNextButton.setEnabled(false);
      cPrevButton.setEnabled(true);
    } else {
      cNextButton.setEnabled(true);
      cPrevButton.setEnabled(true);
    }
  }

  @Override
  public void onPageScrollStateChanged(int i) {
  }
};

谁能指出我在这里做错了什么

你可以用两种方法来做

  • 使用
    界面
    。 通过使用接口,您必须创建类似于
    onGetText(字符串文本)
    的方法。此文本表示您希望在位于“活动”中的文本视图中设置此文本(假定该活动处于活动状态)。因此,在活动中实现接口,并在viewpager的页面更改时调用接口方法
  • 注意:我只是举一个例子,你只想传递文本。但是如果你想的话,你可以传递其他东西

    示例代码:

    public interface Communicator{
      void onGetText(String text);
    }
    
    在您的活动中:

    class CarouselActivity implements Communicator{
      .....
    
      @Override
      void onGetText(String text){
      // You have activity so now access your textView
    }
    }
    
    您必须初始化接口:

    viewPgaerAdapter.init(this);
    
    查看寻呼机中的最后更改:

    private Communicator callback;
    
    public void init(Communicator c){
      callback = c;
    }
    
    ....
    @Override
    onPageSelected(...){
     if(callback!=null){
      callback.onGetText(yourText);
    }
    }
    
  • 使用活动实例。您必须在视图寻呼机中传递活动的上下文。而且活动的文本视图必须是公共的。然后
    ((ActivityName)mContext)活动的publicTextViewOfActivity
  • mContext是您传递的上下文


    我想您会有一些想法。

    您可以向适配器添加方法,使用
    cCurrentPosition
    返回当前选择的
    CarouselModel

    看起来是这样的

    public CarouselModel getItem(Integer position) {
        return result.get(position)
    }
    
    我假设您正在活动中创建适配器实例,在这种情况下,请保存适配器的实例,并修改活动的代码:

     cCopyButton.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
         String msg = mPagerAdapter.getItem(cCurrentPosition);
         Toast toast = Toast.makeText(getApplicationContext(), "Text is " + msg, Toast.LENGTH_LONG);
         toast.show();
    }
    

    }))

    如何将页面添加到寻呼机,将代码添加为“旋转木马复制”按钮应该是旋转木马页面布局的一部分。请发布您的布局文件。您的第一种方法很好,但当viewPager位置为0时,您的第一种方法无法获取文本
     cCopyButton.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
         String msg = mPagerAdapter.getItem(cCurrentPosition);
         Toast toast = Toast.makeText(getApplicationContext(), "Text is " + msg, Toast.LENGTH_LONG);
         toast.show();
    }