MessageFragment.java revision 8369df095a73a77b3715f8ae7ba06089cebca4ce
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dialer.widget;
18
19import android.os.Bundle;
20import android.support.annotation.Nullable;
21import android.support.v4.app.Fragment;
22import android.text.Editable;
23import android.text.InputFilter;
24import android.text.TextUtils;
25import android.text.TextWatcher;
26import android.view.LayoutInflater;
27import android.view.View;
28import android.view.View.OnClickListener;
29import android.view.ViewGroup;
30import android.widget.EditText;
31import android.widget.ImageView;
32import android.widget.LinearLayout;
33import android.widget.TextView;
34import com.android.dialer.common.Assert;
35import com.android.dialer.common.FragmentUtils;
36
37/** Fragment used to compose call with message fragment. */
38public class MessageFragment extends Fragment implements OnClickListener, TextWatcher {
39  private static final String CHAR_LIMIT_KEY = "char_limit";
40  private static final String SHOW_SEND_ICON_KEY = "show_send_icon";
41  private static final String MESSAGE_LIST_KEY = "message_list";
42
43  public static final int NO_CHAR_LIMIT = -1;
44
45  private EditText customMessage;
46  private ImageView sendMessage;
47  private View sendMessageContainer;
48  private TextView remainingChar;
49  private int charLimit;
50
51  private static MessageFragment newInstance(Builder builder) {
52    MessageFragment fragment = new MessageFragment();
53    Bundle args = new Bundle();
54    args.putInt(CHAR_LIMIT_KEY, builder.charLimit);
55    args.putBoolean(SHOW_SEND_ICON_KEY, builder.showSendIcon);
56    args.putStringArray(MESSAGE_LIST_KEY, builder.messages);
57    fragment.setArguments(args);
58    return fragment;
59  }
60
61  @Nullable
62  public String getMessage() {
63    return customMessage == null ? null : customMessage.getText().toString();
64  }
65
66  @Nullable
67  @Override
68  public View onCreateView(
69      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
70    View view = inflater.inflate(R.layout.fragment_message, container, false);
71
72    sendMessage = (ImageView) view.findViewById(R.id.send_message);
73    sendMessageContainer = view.findViewById(R.id.count_and_send_container);
74    if (getArguments().getBoolean(SHOW_SEND_ICON_KEY, false)) {
75      sendMessage.setVisibility(View.VISIBLE);
76      sendMessage.setEnabled(false);
77      sendMessageContainer.setOnClickListener(this);
78    }
79
80    customMessage = (EditText) view.findViewById(R.id.custom_message);
81    customMessage.addTextChangedListener(this);
82    charLimit = getArguments().getInt(CHAR_LIMIT_KEY, NO_CHAR_LIMIT);
83    if (charLimit != NO_CHAR_LIMIT) {
84      remainingChar = (TextView) view.findViewById(R.id.remaining_characters);
85      remainingChar.setVisibility(View.VISIBLE);
86      remainingChar = (TextView) view.findViewById(R.id.remaining_characters);
87      remainingChar.setText("" + charLimit);
88      customMessage.setFilters(new InputFilter[] {new InputFilter.LengthFilter(charLimit)});
89    }
90
91    LinearLayout messageContainer = (LinearLayout) view.findViewById(R.id.message_container);
92    for (String message : getArguments().getStringArray(MESSAGE_LIST_KEY)) {
93      TextView textView = (TextView) inflater.inflate(R.layout.selectable_text_view, null);
94      textView.setOnClickListener(this);
95      textView.setText(message);
96      messageContainer.addView(textView);
97    }
98    return view;
99  }
100
101  @Override
102  public void onClick(View view) {
103    if (view == sendMessageContainer) {
104      if (!TextUtils.isEmpty(customMessage.getText())) {
105        getListener().onMessageFragmentSendMessage(customMessage.getText().toString());
106      }
107    } else if (view.getId() == R.id.selectable_text_view) {
108      customMessage.setText(((TextView) view).getText());
109      customMessage.setSelection(customMessage.getText().length());
110    } else {
111      Assert.fail("Unknown view clicked");
112    }
113  }
114
115  @Override
116  public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
117
118  @Override
119  public void onTextChanged(CharSequence s, int start, int before, int count) {
120    sendMessage.setEnabled(s.length() > 0);
121  }
122
123  @Override
124  public void afterTextChanged(Editable s) {
125    if (charLimit != NO_CHAR_LIMIT) {
126      remainingChar.setText("" + (charLimit - s.length()));
127    }
128    getListener().onMessageFragmentAfterTextChange(s.toString());
129  }
130
131  private Listener getListener() {
132    return FragmentUtils.getParentUnsafe(this, Listener.class);
133  }
134
135  public static Builder builder() {
136    return new Builder();
137  }
138
139  /** Builder for {@link MessageFragment}. */
140  public static class Builder {
141    private String[] messages;
142    private boolean showSendIcon;
143    private int charLimit = NO_CHAR_LIMIT;
144
145    /**
146     * @throws NullPointerException if message is null
147     * @throws IllegalArgumentException if messages.length is outside the range [1,3].
148     */
149    public Builder setMessages(String... messages) {
150      // Since we only allow up to 3 messages, crash if more are set.
151      Assert.checkArgument(messages.length > 0 && messages.length <= 3);
152      this.messages = messages;
153      return this;
154    }
155
156    public Builder showSendIcon() {
157      showSendIcon = true;
158      return this;
159    }
160
161    public Builder setCharLimit(int charLimit) {
162      this.charLimit = charLimit;
163      return this;
164    }
165
166    public MessageFragment build() {
167      return MessageFragment.newInstance(this);
168    }
169  }
170
171  /** Interface for parent activity to implement to listen for important events. */
172  public interface Listener {
173    void onMessageFragmentSendMessage(String message);
174
175    void onMessageFragmentAfterTextChange(String message);
176  }
177}
178