【问题标题】:How to enable on click listener from activity when fragment has been fully loaded?当片段已完全加载时,如何从活动中启用点击监听器?
【发布时间】:2016-05-11 18:44:21
【问题描述】:

我在我的活动中这样声明我的片段:

public void setupViewPager(ViewPager viewP) {
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new ProjectPro1(), "proj1");
        adapter.addFragment(projectPro2 = new ProjectPro2(), "proj2");
        viewP.setAdapter(adapter);
    }

现在,在我的活动结束时,我在一个按钮上调用 setOnClickListener,如果片段完全加载,该按钮工作正常 - 因为当单击该按钮时,该按钮告诉片段不在视图中更新其视图的一部分。但是,如果我立即单击该按钮,它将使应用程序崩溃,因为该片段尚未完全加载并给出空错误。如何在片段完全加载后启用按钮或在片段完全加载时启用 setTheOnClicklistener?

编辑:

为了让事情更清楚 - 我在两个片段上都有一个关注按钮。一个片段只显示图片,另一个片段显示该人的详细信息。如果用户单击任一片段上的关注按钮,则详细信息片段上的计数必须更新(关注者计数 + 1)。

更新:

这是你的答案 adelphus 的尝试 - 这是我的片段类:

    private boolean profileDetailsCreated = false;
    private boolean trackChanged = false;
    private int trackValue = 0;
 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View rootView =  inflater.inflate(R.layout.project_profile_details, container, false);

   profileDetailsCreated = true;

        if(trackChanged) {
            Log.d(Constants.DEBUG, "THE TRACK CHANGED HAS OCCURED BEFORE PROFILE DETAILS CREATED");
            setTrackCount(trackValue);
        }

        return rootView;
}


 public void setTrackCount(int value) {
        Log.d(Constants.DEBUG, "THE value for set track count is " + value);
        if(profileDetailsCreated) {
            Log.d(Constants.DEBUG, "THE PROFILE DETAIL IS CREATED CHANGE SHOULD HAPPEN");
            dbProject.setTrackedCount(trackC + value);
            db.projectUpdateTrack(dbProject);
            trackC = dbProject.getTrackedCount();

            showTrackBackgroundText();
        } else {
            Log.d(Constants.DEBUG, "THE PROFILE DETAIL IS NOT CREATED STORE THE DATA " + value);
            trackValue = value;
            trackChanged = true;
        }

    }

【问题讨论】:

  • 你不能在fragmentonCreateView中设置按钮的onClickListener,而不是activity?
  • 我在两个片段上都使用了按钮
  • 在这种情况下,您可能不应该尝试更新每个片段的任何视图,直到它们被调用 onCreateView()。只需将执行更新所需的信息保存在片段实例本身中,并在调用 onCreateView 时进行更新。
  • 这就是问题所在。只是为了更清楚地绘制图片,我有两个片段 - 第一个显示的片段不受按钮影响但显示它,第二个片段受到影响。现在可以在调用 onCreateView 之后或之前随时单击此按钮,所以如果我保存它,那么我可以让 onCreateView 相应地更改并获取保存的信息,但是在它已经创建之后它将如何被通知...见我在另一个答案上写的评论 - 这似乎是我能想到的唯一解决方案

标签: android android-fragments


【解决方案1】:

根据您的 cmets,我将尝试使我的解释更清楚一些。由于您没有描述更新的作用,因此很难想象您所面临的问题。

这是我的建议(伪代码):

class MainActivity extends Activity {
   public void onCreate(..) {
        ...
        // assuming the button is part of the activity view
        btn.setOnClickListener((View) => {
              Info info = getInfoNeededForUpdate();
              fragment1.update(info);
              fragment2.update(info);
        });
   }
}

// Frag2 is the same logic as Frag1
class Frag1 extends Fragment {
    boolean mCreated;
    Info mPendingInfo;

    public void onCreateView(...) {
         // inflate view, blah
         ...
         // mark us as created
         mCreated = true

         // apply any pending updates         
         if (mPendingInfo != null)
            this.update(info);
    }

    public void update(Info info) {
        // first check if we've been created
        if (this.mCreated) {
            // yep - go ahead and apply the updates to the views
            ...
        } else {
            // nope - save it for later (update will be applied in onCreateView)
            this.mPendingInfo = info;
        }
    }
}

希望您可以从中看出,何时将更新应用于片段并不重要 - 视图将立即更新(如果片段的 onCreateView() 已经被调用)或者它将等到 @987654323 @ 在应用更新之前被调用。

【讨论】:

  • 我正在实现这个,首先我的片段在一个单独的类文件中,其次,我正确地存储它,并且它永远不会在 onCreateView 中使用 if else 语句调用。此外,现在在点击关注按钮之前等待一段时间仍然显示好像从未创建视图...我将添加更改供您查看。
  • @Lion789 您的更新看起来正确。 onCreateView() 在实际显示视图之前通常不会被调用,因此如果您从未显示它,它应该看起来好像从未创建视图。当您说 “它永远不会在 onCreateView 中使用 if else 语句调用” 时,您的意思是 onCreateView() 永远不会在片段上被调用,或者该方法被调用但 trackChanged 的值是假的?
  • 布尔值始终为假,无论我单击按钮多少次,这都没有意义,因为我将其设置为真。我尝试将两个布尔值的初始化都删除,但我的日志中的 profileDetailsCreated 始终显示为 false。
  • 不确定我是否可以在不亲自调试代码的情况下帮助您完成这一点。如果您在setTrackCount() 中看到正确的调试消息,则看起来该片段的多个实例正在构建,但没有完整代码,我不确定该建议什么。也许尝试在片段构造函数中设置断点,setTrackCount()onCreateView() 以查看调用了什么。
  • 似乎 profileDetailsCreated 在 onCreateView 中为真 - 但是当从活动中调用该方法时,它在 setTrackCount 上的值...
【解决方案2】:

在这种情况下,您应该在onActivityCreated生命周期方法中设置OnClickListener

private Button yourButton;
public void onActivityCreated(Bundle savedInstanceState) {  
    super.onActivityCreated(savedInstanceState);
    View rooView = getView();
    yourButton  = (Button) rooView.findViewById(R.id.your_button);
    //then you can set the 
    yourButton.setOnClickListener(new OnClickListener() {           
            @Override
            public void onClick(View v) {
                //do stuff here!    
            }
        }); 
}

【讨论】:

  • 如果我没有使用按钮的两个片段,这会很好,因此我在活动视图中有按钮,两个片段都占用按钮和操作栏之间的空间 - 因此我有在活动中设置onclick而不是在片段中......我能想到的唯一解决方案是在加载片段时设置onclicklistener并调用活动的接口来设置onClick
  • 所以你说两个片段都使用一个按钮?那么在这种情况下,按钮不在片段的布局文件之一中,而是在活动中?这些片段用按钮做什么?
  • 很抱歉看到编辑,举了一个真实的例子,让它更清楚
猜你喜欢
  • 2017-07-13
  • 2014-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多