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 17 package com.android.dialer.widget; 18 19 import android.os.Bundle; 20 import android.support.annotation.Nullable; 21 import android.support.v4.app.Fragment; 22 import android.text.Editable; 23 import android.text.InputFilter; 24 import android.text.TextUtils; 25 import android.text.TextWatcher; 26 import android.view.LayoutInflater; 27 import android.view.View; 28 import android.view.View.OnClickListener; 29 import android.view.ViewGroup; 30 import android.widget.EditText; 31 import android.widget.ImageView; 32 import android.widget.LinearLayout; 33 import android.widget.TextView; 34 import com.android.dialer.common.Assert; 35 import com.android.dialer.common.FragmentUtils; 36 37 /** Fragment used to compose call with message fragment. */ 38 public 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