如何从当前ViewPager视图获取Activity中的TextView

时间:2019-07-12 12:28:33

标签: android nullpointerexception android-viewpager android-pageradapter

我是Android开发的新手。出于学习目的,我正在尝试创建类似可滑动轮播的内容。我正在使用ViewPager的帮助下,然后使用PagerAdapter。

我正在用JSON数据填充视图,并且工作正常。使用JSON加载和显示数据没有问题。问题是,当我尝试在“轮播”活动中获取当前View的数据时,出现了Null指针异常。

我想从viewpager中的当前视图复制/获取数据。为此,我试图获取当前视图,然后使用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);
  }
}

它还利用了Model类,如下所示:

public class CarouselModel {
  String description;

  public CarouselModel(String description) {
    this.description = description;
  }

  public String getDescription() {
    return description;
  }
}

现在在我的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) {
  }
};

任何人都可以指出我在做什么错吗?

2 个答案:

答案 0 :(得分:0)

您可以通过两种方式来实现。

  1. 使用Interface。 通过使用Interface,您必须创建类似onGetText(String text)的方法。此文本表示您要在位于Activity中的TextView中设置此文本(假定该活动处于活动状态)。因此,在viewpager页面更改时,请在您的Activity中实现该接口并调用接口方法

注意:我仅举一个例子,您只希望传递文本。但是如果您愿意,您可以传递其他内容。

示例代码:

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);
}
}
  1. 使用活动实例。您必须在视图寻呼机中传递活动上下文。并且Activity的TextView必须是公共的。然后((ActivityName)mContext)publicTextViewOfActivity

mContext是您传递的上下文。

我想你会有所想法的。

答案 1 :(得分:0)

您可以将方法添加到适配器,该方法使用CarouselModel

返回当前选择的cCurrentPosition

它看起来像这样

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();
}

});