问题描述
我有一个具有包含片段容器中的活动,这个片段有其他片段。
现在我要访问主要活动的意见本次或儿童片段,但它返回空指针异常。
类:
公共类ImageListFragment扩展AbsListViewBaseFragment实现ObservableScrollViewCallbacks {公共静态最终诠释指数= 0;
android.support.design.widget.FloatingActionButton mFab;@Bind(R.id.ic_call)
ImageView的mIcCall;
@Bind(R.id.ic_email)
ImageView的mIcEmail;
@Bind(R.id.ic_forum)
ImageView的mIcForum;
FabToolbar mFabToolbar;
ObservableListView mObservableListView;
@覆盖
公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,捆绑savedInstanceState){
查看rootView = inflater.inflate(R.layout.fr_image_list,集装箱,FALSE);
ListView控件=(ListView控件)rootView.findViewById(android.R.id.list);
((ListView中)的ListView).setAdapter(新ImageAdapter(getActivity())); 最后的子选项卡mainActivity =(子选项卡)getActivity();
ButterKnife.bind(mainActivity);
////////////////问题就在这里
mFabToolbar =(FabToolbar)rootView.findViewById(R.id.fabtoolbar);
////////////////
。getFragmentManager()findFragmentByTag(TAG);
// rootView.findViewById(R.id.fab);
mObservableListView =(ObservableListView)rootView.findViewById(android.R.id.list);
//
mObservableListView.setAdapter(this.listView.getAdapter());
mObservableListView.setScrollViewCallbacks(本); mainActivity.mFab.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
Toast.makeText(mainActivity.getApplicationContext(),MSG msg中,Toast.LENGTH_LONG).show();
mainActivity.mFabToolbar.expandFab();
}
}); listView.setOnItemClickListener(新OnItemClickListener(){
@覆盖
公共无效onItemClick(适配器视图<>母公司,观景,INT位置,长的id){ startImagePagerActivity(位置);
}
});
返回rootView;
}@覆盖
公共无效的onDestroy(){
super.onDestroy();
AnimateFirstDisplayListener.displayedImages.clear();
}私有静态类ImageAdapter延伸BaseAdapter { 私有静态最后的String [] = IMAGE_URLS Constants.IMAGES; 私人LayoutInflater吹气;
私人ImageLoadingListener animateFirstListener =新AnimateFirstDisplayListener(); 私人DisplayImageOptions选择; ImageAdapter(上下文的背景下){
充气= LayoutInflater.from(上下文); 选项=新DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)//تغييرالفيوقبلتحميلالصورة
.showImageForEmptyUri(R.drawable.ic_empty)//لماالصورةفاضية
.showImageOnFail(R.drawable.ic_error)//عندالفشل
.cacheInMemory(真)
.cacheOnDisk(真)
.considerExifParams(真)
.displayer(新CircleBitmapDisplayer(Color.WHITE,5))
。建立();
} @覆盖
公众诠释的getCount(){
返回IMAGE_URLS.length;
} @覆盖
公共对象的getItem(INT位置){
返回的位置;
} @覆盖
众长getItemId(INT位置){
返回的位置;
} @覆盖
公共查看getView(最终诠释的立场,观点convertView,父母的ViewGroup){
查看查看= convertView;
最后ViewHolder持有人;
如果(convertView == NULL){
鉴于= inflater.inflate(R.layout.item_list_image,父母,假);
持有人=新ViewHolder();
holder.text =(TextView中)view.findViewById(R.id.text);
holder.image =(ImageView的)view.findViewById(R.id.image);
view.setTag(保持器);
}其他{
支架=(ViewHolder)view.getTag();
} holder.text.setText(项目+(位置+ 1)); 。ImageLoader.getInstance()displayImage(IMAGE_URLS [位置],holder.image,期权,animateFirstListener); 返回视图。
}
}静态类ViewHolder {
TextView的文本;
ImageView的形象;
}@覆盖
公共无效onScrollChanged(INT I,布尔B,B1布尔){}@覆盖
公共无效onDownMotionEvent(){}@覆盖
公共无效onUpOrCancelMotionEvent(ScrollState scrollState){
Log.d(,滚动滚动滚动); 如果(scrollState == ScrollState.UP){
mFabToolbar.slideOutFab();
}否则如果(scrollState == ScrollState.DOWN){
mFabToolbar.slideInFab();
}
}@OnClick(R.id.fab)
无效onFabClick(){
mFabToolbar.expandFab();
}@OnClick(R.id.call)
无效onClickCall(){
iconAnim(mIcCall);
}@OnClick(R.id.ic_email)
无效onClickEmail(){
iconAnim(mIcEmail);
}@OnClick(R.id.ic_forum)
无效onClickForum(){
iconAnim(mIcForum);
}私人无效iconAnim(查看图标){
动画iconAnim = ObjectAnimator.ofPropertyValuesHolder(
图标,
PropertyValuesHolder.ofFloat(将scaleX,1F,1.5F,1F)
PropertyValuesHolder.ofFloat(的scaleY,1F,1.5F,1F));
iconAnim.start();
}私有静态类AnimateFirstDisplayListener扩展SimpleImageLoadingListener { 静态最终名单<串GT; displayedImages = Collections.synchronizedList(新的LinkedList<串GT;()); @覆盖
公共无效onLoadingComplete(字符串imageUri,观景,位图loadedImage){
如果(loadedImage!= NULL){
ImageView的ImageView的=(ImageView的)视图。
!布尔firstDisplay = displayedImages.contains(imageUri);
如果(firstDisplay){
FadeInBitmapDisplayer.animate(ImageView的,500);
displayedImages.add(imageUri);
}
}
}
}
}
这不是很好的做法,发现和控制这样一个观点。意见很容易成为从活动脱落,导致意外的异常。
您应该相当了解如何使用回调如果需要片段和活动之间进行通信。这样一来,它也让你的code。在正确的位置 - 这样的活动是唯一一个触摸自己的看法和碎片也才触动了自己的看法。它只是告诉活性(通过回调)出事了,该活动可能想知道的。它还确保所述片段是完全自包含的,并且可以容易地重复使用。
您可以了解如何在这里实现回调:
I have an activity that has container that contain fragments and this fragment has other fragments.
Now I want this second or child fragment to access views in main activity, but it returns null pointer exception.
class:
public class ImageListFragment extends AbsListViewBaseFragment implements ObservableScrollViewCallbacks {
public static final int INDEX = 0;
android.support.design.widget.FloatingActionButton mFab;
@Bind(R.id.ic_call)
ImageView mIcCall;
@Bind(R.id.ic_email)
ImageView mIcEmail;
@Bind(R.id.ic_forum)
ImageView mIcForum;
FabToolbar mFabToolbar;
ObservableListView mObservableListView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fr_image_list, container, false);
listView = (ListView) rootView.findViewById(android.R.id.list);
((ListView) listView).setAdapter(new ImageAdapter(getActivity()));
final SubTaB mainActivity = (SubTaB)getActivity();
ButterKnife.bind(mainActivity);
//////////////// problem here
mFabToolbar = (FabToolbar) rootView.findViewById(R.id.fabtoolbar);
////////////////
getFragmentManager().findFragmentByTag("TAG");
// rootView.findViewById(R.id.fab);
mObservableListView = (ObservableListView)rootView.findViewById(android.R.id.list);
//
mObservableListView.setAdapter(this.listView.getAdapter());
mObservableListView.setScrollViewCallbacks(this);
mainActivity.mFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mainActivity.getApplicationContext(), "msg msg", Toast.LENGTH_LONG).show();
mainActivity.mFabToolbar.expandFab();
}
});
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
startImagePagerActivity(position);
}
});
return rootView;
}
@Override
public void onDestroy() {
super.onDestroy();
AnimateFirstDisplayListener.displayedImages.clear();
}
private static class ImageAdapter extends BaseAdapter {
private static final String[] IMAGE_URLS = Constants.IMAGES;
private LayoutInflater inflater;
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
private DisplayImageOptions options;
ImageAdapter(Context context) {
inflater = LayoutInflater.from(context);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub) // تغيير الفيو قبل تحميل الصورة
.showImageForEmptyUri(R.drawable.ic_empty) // لما الصورة فاضية
.showImageOnFail(R.drawable.ic_error) // عند الفشل
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.displayer(new CircleBitmapDisplayer(Color.WHITE, 5))
.build();
}
@Override
public int getCount() {
return IMAGE_URLS.length;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
final ViewHolder holder;
if (convertView == null) {
view = inflater.inflate(R.layout.item_list_image, parent, false);
holder = new ViewHolder();
holder.text = (TextView) view.findViewById(R.id.text);
holder.image = (ImageView) view.findViewById(R.id.image);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.text.setText("Item " + (position + 1));
ImageLoader.getInstance().displayImage(IMAGE_URLS[position], holder.image, options, animateFirstListener);
return view;
}
}
static class ViewHolder {
TextView text;
ImageView image;
}
@Override
public void onScrollChanged(int i, boolean b, boolean b1) {
}
@Override
public void onDownMotionEvent() {
}
@Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
Log.d("","Scroll scroll scroll");
if (scrollState == ScrollState.UP) {
mFabToolbar.slideOutFab();
} else if (scrollState == ScrollState.DOWN) {
mFabToolbar.slideInFab();
}
}
@OnClick(R.id.fab)
void onFabClick() {
mFabToolbar.expandFab();
}
@OnClick(R.id.call)
void onClickCall() {
iconAnim(mIcCall);
}
@OnClick(R.id.ic_email)
void onClickEmail() {
iconAnim(mIcEmail);
}
@OnClick(R.id.ic_forum)
void onClickForum() {
iconAnim(mIcForum);
}
private void iconAnim(View icon) {
Animator iconAnim = ObjectAnimator.ofPropertyValuesHolder(
icon,
PropertyValuesHolder.ofFloat("scaleX", 1f, 1.5f, 1f),
PropertyValuesHolder.ofFloat("scaleY", 1f, 1.5f, 1f));
iconAnim.start();
}
private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
if (loadedImage != null) {
ImageView imageView = (ImageView) view;
boolean firstDisplay = !displayedImages.contains(imageUri);
if (firstDisplay) {
FadeInBitmapDisplayer.animate(imageView, 500);
displayedImages.add(imageUri);
}
}
}
}
}
It is not good practise to find and control a view in this way. Views can easily become detached from activities and cause unexpected exceptions.
You should rather look at using callbacks to communicate between fragments and activities if required. That way, it also keeps your code in the correct places - so the activity is the only one touching its own views and the fragment also only touches its own views. It merely tells the activity (via callbacks) that something has happened that the activity might want to know about. It also ensures that the fragments are completely self contained and can be easily reused.
You can read about how to implement callbacks here: http://developer.android.com/training/basics/fragments/communicating.html
这篇关于从片段访问的主要活动视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!