1

这是我的目标: 图片

我不确定我是否正确执行此操作。可能有更好、更有效和更清洁的方法来做到这一点,但我需要知道如何做。

此布局是用 xml 设计的,并通过充气机充气。然后将生成的视图放置到 AlertDialog 中。因此,这被用户视为一个 AlertDialog。

我关心的是底部的标签部分。我希望它像 Tumblr 标签一样工作。键入一个字符串,点击按钮,带有该标签名称的按钮将显示在其下方的空白部分。

现在,如果您单击这些按钮(带有各自的标签名称),它们将从框架中消失。

我有几个担忧。

  1. 我在实现监听器时遇到了麻烦。如果 AddTag 按钮在(当前不可见,但存在)LinearLayout 中创建更多按钮,那么创建的按钮呢?如果这些按钮是在从 AddTag 按钮的 onClick 方法定义的某个内部方法中创建的,那么这些按钮如何实现将自己从 LinearLayout 中删除的 onClick 侦听器?

  2. 我担心必须将其中一些视图声明为 FINAL 才能在按钮方法和内部类中引用它们。我现在因此而陷入困境。

  3. 我必须为标签按钮定义自己的布局吗?你看,一个LinearLayout一个接一个地显示东西,是吗?我想尝试重新创建一些社交网站是如何做到的。用按钮从上到下,从左到右填充布局。如果当前行没有剩余空间,请转到下一个并在此处添加标签按钮。它基本上是一个具有自动换行功能的动态 LinearLayout。

如果有任何更好的方法来实现这一点,请让我一步一步知道该怎么做。我还没有学习 Fragments,但我认为它在这里可能非常适用。另外,我是否应该创建一个扩展 ViewGroup 的类,在那里扩展 XML,并添加辅助方法来处理事情?我想我可以从 DialogFragment 中添加视图(我刚刚创建的类)并从那里开始工作?

顺便说一下,这是我当前的代码。我被困住了。

/**
    * Opens a view for the user to define their new action and add it to the
    * dictionary.
    * 
    * @param view
    */
   public void defineNewAction(View view) {
      final AlertDialog.Builder builder = new AlertDialog.Builder(this);
      LayoutInflater inflater = this.getLayoutInflater();
      View viewToSet = inflater.inflate(
            R.layout.define_new_action_window_layout,
            null);      

      final EditText newActionName = (EditText) viewToSet
            .findViewById(R.id.set_action_name);

      final RadioGroup priorityGroup = (RadioGroup) viewToSet
            .findViewById(R.id.radiogroup_set_priority);

      final EditText goalTimeHours = (EditText) viewToSet
            .findViewById(R.id.set_goal_time_hours);

      final EditText goalTimeMinutes = (EditText) viewToSet
            .findViewById(R.id.set_goal_time_minutes);

      final EditText addTagsInput = (EditText) viewToSet
            .findViewById(R.id.add_tags_input);
      Button addTagButton = (Button) viewToSet.findViewById(R.id.btn_add_tags);
      final ArrayList<String> tags = new ArrayList<String>();

      final LinearLayout currentTagsLayout = (LinearLayout) viewToSet
            .findViewById(R.id.current_tags);
      addTagButton.setOnClickListener(new View.OnClickListener() {

         public void onClick(View v) {
            String tag = addTagsInput.getText().toString();
            tags.add(tag);
            Button newTag = new Button(builder.getContext());
            int tagId = tag.hashCode();
            if (tagId < 0)
               tagId *= -1;
            newTag.setId(tagId);

            newTag.setOnClickListener(new View.OnClickListener() {

               public void onClick(View v) {
                  Button toRemove = (Button) currentTagsLayout.findViewById(tagId);
                  currentTagsLayout.removeView(toRemove);
               }
            });

            currentTagsLayout.addView(newTag);
         }
      });

      builder.setTitle("Define your action.");
      builder.setView(viewToSet);
      builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

         public void onClick(DialogInterface arg0, int arg1) {
            String name = newActionName.getText().toString();
            int priority = priorityGroup.getCheckedRadioButtonId();
            int goalHours = Integer
                  .parseInt(goalTimeHours.getText().toString());
            int goalMinutes = Integer.parseInt(goalTimeMinutes.getText()
                  .toString());
         }

      });
      builder.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {

               public void onClick(DialogInterface arg0, int arg1) {

               }
            });
      AlertDialog dialog = builder.create();
      dialog.show();
   }
4

1 回答 1

1

I have trouble implementing listeners

There's no trouble. For the functionality you are trying to achieve, you can keep adding buttons and setting OnClickListeners on them. You don't even need to give them an id, or track them in any way. The following code inside your OnClickListener will do:

newTag.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {

        // Use the View given to you
        currentTagsLayout.removeView(v);

    }
});

I am afraid about having to declare some of these views as FINAL

This is how Java works. I haven't noticed any crippling effects of this. You can also declare your variables as global to not have to define them as final. But I don't see why declaring them as final is an issue. Could you provide an example where this is a problem?

Do I have to define my own layout for the tag buttons?

This is something you will have to deal with yourself. It's a design decision. If you need auto-wrapping support, you can look at Android Flow Layout: Link. It's an extended LinearLayout that supports auto-wrap of its contents.

I have not learned Fragments yet, but I think it may be VERY applicable here

I don't see why they would be.

Note/Aside: Some kind of a check here would be better:

String tag = "";

if (!addTagsInput.getText().toString().equals("")) {
    tag = addTagsInput.getText().toString();
} else {
    // handle empty string
}
于 2013-09-10T17:56:18.120 回答