2012-07-03 11 views
23

私は検索していますが、これに対する回答は見つかりませんでした。私が実装しようとしているのは、ICS gmailアプリケーションの作成画面にある 'To'フィールドに似たEditTextです。ここでタグのような機能を備えたカスタムeditTextを作成する

は、私が欲しいものを記述した画像です: enter image description here

私はEditTextを拡張し、独自のカスタムEditTextクラスを実装すると思っていますが、私はそれを行う方法は本当にわからないか、それが最善の解決策だ場合でも、 。何かご意見は?

+1

カフを外すと、「タグ」の「ImageSpan」要素を含む「Spannable」に通常の「EditText」が表示されていると思います。しかし、それらの "x"部分がタップしてタグを取り除くことを意味するならば、それは 'ImageSpan'では可能ではないと私は考えています。 – CommonsWare

+1

ええ、それは妥当だと思うけど、グーグルは自分のGmailアプリケーションで(それを削除するために小さな「x」で)動作するようになったので、どこか完全な解決策があると確信しています。うまくいけば、あまりにも多くのハッキングではない –

+0

@BillX:あなたはどのような解決方法を使用することを知っていますか?ありがとう! – Loc

答えて

4

Hmでも同様の質問がありますが、closest answer I foundです。私は以前にこの種の問題を抱えていたことを他の人が知っていたCommonsWareのおかげで私は正しい方向に向いています。

4

私は良い解決策を見つけることができませんでしたので、私は自分のライブラリを構築して、これを処理します:TokenAutoComplete

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:background="@drawable/token_background"> 
    <TextView android:id="@+id/name" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textColor="@android:color/white" 
     android:textSize="14sp" 
     android:text="Test Me" 
     android:padding="2dp" /> 

    <ImageView 
     android:layout_height="10dp" 
     android:layout_width="10dp" 
     android:src="@drawable/x" 
     android:layout_gravity="center_vertical" 
     android:layout_marginLeft="3dp" 
     android:layout_marginRight="5dp" /> 
</LinearLayout> 

トークンbackgound描画可能

<shape xmlns:android="http://schemas.android.com/apk/res/android" > 
    <solid android:color="#ffafafaf" /> 
    <corners 
     android:topLeftRadius="5dp" 
     android:bottomLeftRadius="5dp" 
     android:topRightRadius="5dp" 
     android:bottomRightRadius="5dp" /> 
</shape> 

Personオブジェクト・コード

(あなたがあなた自身のx描画可能を見つける必要があります)contact_tokenため

public class ContactsCompletionView extends TokenCompleteTextView { 
    public ContactsCompletionView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    protected View getViewForObject(Object object) { 
     Person p = (Person)object; 

     LayoutInflater l = (LayoutInflater)getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
     LinearLayout view = (LinearLayout)l.inflate(R.layout.contact_token, (ViewGroup)ContactsCompletionView.this.getParent(), false); 
     ((TextView)view.findViewById(R.id.name)).setText(p.getName()); 

     return view; 
    } 

    @Override 
    protected Object defaultObject(String completionText) { 
     //Stupid simple example of guessing if we have an email or not 
     int index = completionText.indexOf('@'); 
     if (index == -1) { 
      return new Person(completionText, completionText.replace(" ", "") + "@example.com"); 
     } else { 
      return new Person(completionText.substring(0, index), completionText); 
     } 
    } 
} 

レイアウトコード:ここでは基本的な例です

public class Person implements Serializable { 
    private String name; 
    private String email; 

    public Person(String n, String e) { name = n; email = e; } 

    public String getName() { return name; } 
    public String getEmail() { return email; } 

    @Override 
    public String toString() { return name; } 
} 

サンプルacti VITY

public class TokenActivity extends Activity { 
    ContactsCompletionView completionView; 
    Person[] people; 
    ArrayAdapter<Person> adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     people = new Person[]{ 
       new Person("Marshall Weir", "[email protected]"), 
       new Person("Margaret Smith", "[email protected]"), 
       new Person("Max Jordan", "[email protected]"), 
       new Person("Meg Peterson", "[email protected]"), 
       new Person("Amanda Johnson", "[email protected]"), 
       new Person("Terry Anderson", "[email protected]") 
     }; 

     adapter = new ArrayAdapter<Person>(this, android.R.layout.simple_list_item_1, people); 

     completionView = (ContactsCompletionView)findViewById(R.id.searchView); 
     completionView.setAdapter(adapter); 
     completionView.setTokenClickStyle(TokenCompleteTextView.TokenClickStyle.Delete); 
    } 
} 

レイアウトコード

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <com.tokenautocomplete.ContactsCompletionView 
     android:id="@+id/searchView" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

</RelativeLayout> 
+0

私は同じBillXの状況にいます。あなたのソリューションがx-closeボタンで動作することは分かりますか?ありがとう。 – Loc

+0

@LocHa x-closeボタンの機能は何ですか? –

+0

@SwapnilSonar:完全な解決策が見つかりませんでした。私はタグを編集する独自の方法を作りました(BillXが望むようなものではありません)。何かを学ぶことができますkpbird.com/2013/02/android-chips-edittext-token-edittext.html – Loc

5

this answerから溶液適応します。コンマを挿入するときに自動的に入力を区切ります(セパレータは調整可能です)。 ImageSpanとClickableSpanを作成します(エントリは右の部分をクリックすることで削除できます)。

public class TagEditText extends EditText { 

    TextWatcher textWatcher; 

    String lastString; 

    String separator = ","; 

    public TagEditText(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 


    private void init() { 
     setMovementMethod(LinkMovementMethod.getInstance()); 

     textWatcher = new TextWatcher() { 
      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

      } 

      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 
       String thisString = s.toString(); 
       if (thisString.length() > 0 && !thisString.equals(lastString)) { 
        format(); 

       } 
      } 
     }; 

     addTextChangedListener(textWatcher); 
    } 


    private void format() { 

     SpannableStringBuilder sb = new SpannableStringBuilder(); 
     String fullString = getText().toString(); 

     String[] strings = fullString.split(separator); 


     for (int i = 0; i < strings.length; i++) { 

      String string = strings[i]; 
      sb.append(string); 

      if (fullString.charAt(fullString.length() - 1) != separator.charAt(0) && i == strings.length - 1) { 
       break; 
      } 

      BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(createTokenView(string)); 
      bd.setBounds(0, 0, bd.getIntrinsicWidth(), bd.getIntrinsicHeight()); 

      int startIdx = sb.length() - (string.length()); 
      int endIdx = sb.length(); 

      sb.setSpan(new ImageSpan(bd), startIdx, endIdx, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

      MyClickableSpan myClickableSpan = new MyClickableSpan(startIdx, endIdx); 
      sb.setSpan(myClickableSpan, Math.max(endIdx-2, startIdx), endIdx, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 

      if (i < strings.length - 1) { 
       sb.append(separator); 
      } else if (fullString.charAt(fullString.length() - 1) == separator.charAt(0)) { 
       sb.append(separator); 
      } 
     } 


     lastString = sb.toString(); 

     setText(sb); 
     setSelection(sb.length()); 

    } 

    public View createTokenView(String text) { 


     LinearLayout l = new LinearLayout(getContext()); 
     l.setOrientation(LinearLayout.HORIZONTAL); 
     l.setBackgroundResource(R.drawable.bordered_rectangle_rounded_corners); 

     TextView tv = new TextView(getContext()); 
     l.addView(tv); 
     tv.setText(text); 
     tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); 

     ImageView im = new ImageView(getContext()); 
     l.addView(im); 
     im.setImageResource(R.drawable.ic_cross_15dp); 
     im.setScaleType(ImageView.ScaleType.FIT_CENTER); 

     return l; 
    } 

    public Object convertViewToDrawable(View view) { 
     int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); 
     view.measure(spec, spec); 
     view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); 

     Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888); 

     Canvas c = new Canvas(b); 

     c.translate(-view.getScrollX(), -view.getScrollY()); 
     view.draw(c); 
     view.setDrawingCacheEnabled(true); 
     Bitmap cacheBmp = view.getDrawingCache(); 
     Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true); 
     view.destroyDrawingCache(); 
     return new BitmapDrawable(getContext().getResources(), viewBmp); 
    } 

    private class MyClickableSpan extends ClickableSpan{ 

     int startIdx; 
     int endIdx; 

     public MyClickableSpan(int startIdx, int endIdx) { 
      super(); 
      this.startIdx = startIdx; 
      this.endIdx = endIdx; 
     } 

     @Override 
     public void onClick(View widget) { 



      String s = getText().toString(); 

      String s1 = s.substring(0, startIdx); 
      String s2 = s.substring(Math.min(endIdx+1, s.length()-1), s.length()); 

      TagEditText.this.setText(s1 + s2); 
     } 

    } 
} 

R.drawable.bordered_rectangle_rounded_corners:

<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
    <solid 
     android:color="@color/transparent"/> 
    <stroke android:width="1dp" android:color="#AAAAAA" /> 
    <corners 
     android:radius="100dp" /> 
    <padding 
     android:left="5dp" 
     android:top="5dp" 
     android:right="5dp" 
     android:bottom="5dp" /> 
</shape> 

追加する最後のものは、 "X-ボタン" のためのpngされます。これまでのところうまくいきましたが、問題を解決するにはdeleteキーの長押しがうまくいきません(誰かがそれを働かせる方法を知っていれば自由にコメントしてください)

+0

私はこれを追加すると最初にカーソルが点滅するのを見ることができないのだろうかと思っていました。 – prateek31

1

この問題を解決するためにlibraryを作成しました。自由にそれを使用して貢献してください。

+0

あなたの素敵なライブラリを使用して、私に教えてもらえますか?SoftKeyboardのプレス(削除)の後ろからタグを削除するにはどうすればいいですか? – Dhiren

関連する問題