Monday, June 22, 2015

How to align TextView around an ImageView




We can achieve this by using the android.text.style.LeadingMarginSpan.LeadingMarginSpan2 interface which is available in API 8.

An extended version of LeadingMarginSpan, which allows the implementor to specify the number of lines of the paragraph to which this object is attached that the "first line of paragraph" margin width will be applied to.

There should only be one LeadingMarginSpan2 per paragraph. The leading margin line count affects all LeadingMarginSpans in the paragraph, adjusting the number of lines to which the first line margin is applied.

As with LeadingMarginSpans, LeadingMarginSpan2s should be attached from the beginning to the end of a paragraph.


Reference :: 
http://developer.android.com/reference/android/text/style/LeadingMarginSpan.LeadingMarginSpan2.html



Create Custom Leading Margin
class CustomLeadingMargin implements LeadingMarginSpan2 {
        
        private int marginSpace;
        private int numberOfLines;

        CustomLeadingMargin(int numberOfLines, int marginSpace) {
            this.numberOfLines = numberOfLines;
  this.marginSpace = marginSpace;
        }

        @Override
        public int getLeadingMargin(boolean firstLineFlag) {
        return firstLineFlag ? marginSpace : 0;
        }

        @Override
        public int getLeadingMarginLineCount() {
            return numberOfLines;
        }

        @Override
        public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, 
                int top, int baseline, int bottom, CharSequence text, 
                int start, int end, boolean first, Layout layout) {}
}


Apply in the TextView

//Get the string from the String File
String descText = getString(R.string.description);

Drawable dIcon = getResources().getDrawable(R.drawable.icon);
int leftMargin = dIcon.getIntrinsicWidth() + 5;

ImageView icon = (ImageView) findViewById(R.id.startImage);
icon.setBackgroundDrawable(dIcon);

SpannableString mSpannableString = new SpannableString(descText);
ss.setSpan(new CustomLeadingMargin(3, leftMargin), 0, mSpannableString.length(), 0);

((TextView) findViewById(R.id.message_view)).setText(mSpannableString);


Full Implementation

public class LeadingMarginSampleActivity extends Activity {

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

        //Get the string from the String File        String descText = "An extended version of LeadingMarginSpan, which allows the implementor to specify the number of lines of the paragraph to which this object is attached that the \"first line of paragraph\" margin width will be applied to.";

        Drawable dIcon = getResources().getDrawable(R.drawable.ic_launcher);
        int leftMargin = dIcon.getIntrinsicWidth() + 5;

        ImageView icon = (ImageView) findViewById(R.id.startImage);
        icon.setBackgroundDrawable(dIcon);

        SpannableString mSpannableString = new SpannableString(descText);
        mSpannableString.setSpan(new CustomLeadingMargin(3, leftMargin), 0, mSpannableString.length(), 0);

        ((TextView) findViewById(R.id.description)).setText(mSpannableString);

    }

    class CustomLeadingMargin implements LeadingMarginSpan.LeadingMarginSpan2 {

        private int numberOfLines;
        private int marginSpace;

        CustomLeadingMargin(int numberOfLines, int marginSpace) {
            this.numberOfLines = numberOfLines;
            this.marginSpace = marginSpace;
        }

        @Override        public int getLeadingMargin(boolean firstLineFlag) {
            return firstLineFlag ? marginSpace : 0;
        }

        @Override        public int getLeadingMarginLineCount() {
            return numberOfLines;
        }

        @Override        public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
                                      int top, int baseline, int bottom, CharSequence text,
                                      int start, int end, boolean first, Layout layout) {
        }
    }

}

activity_leading_margin_sample.xml

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

    <TextView        android:id="@+id/description"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="@string/descText" />

    <ImageView        android:id="@+id/startImage"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@drawable/ic_launcher" />
</RelativeLayout>

Output



Sunday, December 21, 2014

Sample Search Implementation using TextWatcher

In this example, we will learn how to implement a search functionality in a listview using filters in your Android application. A listview can be filtered by the user input and is enabled using addTextChangedListener method. The search function will filter the listview with a matching string from the user input. Searching through the listview provides users an easy way to find the information they needed. We will create a listview with an edittext placed on top and on text input will filter the results and on listview item click will open a new activity. So lets begin…

public class SampleSearch extends Activity implements TextWatcher {

ArrayList arraylist = new ArrayList();

private void loadData() {
arraylist.add(new CustomVO("Ganesan"));
arraylist.add(new CustomVO("Ram"));
arraylist.add(new CustomVO("Ravi"));
arraylist.add(new CustomVO("Varshika"));
}

ListView listview;
EditText editsearch;
MyAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_search);
loadData();
listview = (ListView) findViewById(R.id.list_view);
editsearch = (EditText) findViewById(R.id.search_view);
adapter = new MyAdapter(this, android.R.layout.simple_list_item_1,
arraylist);
listview.setAdapter(adapter);
editsearch.addTextChangedListener(this);
}

@Override
public void afterTextChanged(Editable arg0) {
String text = editsearch.getText().toString()
.toLowerCase(Locale.getDefault());
adapter.filter(text);
}

@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}

@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}

@SuppressLint("DefaultLocale")
public class MyAdapter extends ArrayAdapter {
ArrayList list;
ArrayList allDataList = new ArrayList();
private LayoutInflater mInflater;

public MyAdapter(Context context, int resource, ArrayList list) {
super(context, resource, list);
this.list = list;
this.allDataList.addAll(list);
mInflater = LayoutInflater.from(context);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

final ViewHolder holder;
if (convertView == null) {

holder = new ViewHolder();
convertView = mInflater.inflate(
android.R.layout.simple_list_item_1, null);
holder.name = (TextView) convertView
.findViewById(android.R.id.text1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}

holder.name.setText(list.get(position).getName());
return convertView;
}

// Filter Class
@SuppressLint("DefaultLocale")
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
list.clear();
System.out.println(charText);

System.out.println(charText.length() == 0);

if (charText.length() == 0) {
list.addAll(allDataList);
} else {

for (CustomVO customVO : allDataList) {
if (customVO.getName().toLowerCase()
.contains(charText.toLowerCase())) {
list.add(customVO);
}
}
}
System.out.println(list);
notifyDataSetChanged();
}

class ViewHolder {
TextView name;
}

}

public class CustomVO {
private String name;

public CustomVO(String name) {
super();
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}


}


Layout.xml
xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/search_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#FF0000" />

</LinearLayout>