Implement Tag functionality like Instagram? - android

In this demo I want to add tag functionality like Instagram. when I search a follower using # its work properly and show name of that follower. but when I erase # in search it shows error. java.lang.StringIndexOutOfBoundsException: length=0; index=1. I use many code but not solve.need help Code is here:-
public class Main2Activity extends AppCompatActivity {
RecyclerView following_userr_list, mListView_COmment;
EditText editTextSearch;
ArrayList<String> FollowingListValuesArr;
ArrayList<String> show_following;
CustomAdapter adapter;
Custom_comment_Adapter adapter1;
String final_string = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
FollowingListValuesArr = new ArrayList<>();
FollowingListValuesArr.add("Ramiz");
FollowingListValuesArr.add("Karan");
FollowingListValuesArr.add("Azad");
FollowingListValuesArr.add("Manish");
show_following = new ArrayList<>();
show_following.add("Ramiz");
show_following.add("Karan");
show_following.add("Azad");
show_following.add("Manish");
following_userr_list = (RecyclerView) findViewById(recyclerView);
editTextSearch = (EditText) findViewById(R.id.editTextSearch);
mListView_COmment = (RecyclerView) findViewById(recyclerView_comment);
following_userr_list.setHasFixedSize(true);
following_userr_list.setLayoutManager(new LinearLayoutManager(this));
mListView_COmment.setHasFixedSize(true);
mListView_COmment.setLayoutManager(new LinearLayoutManager(this));
adapter = new CustomAdapter(FollowingListValuesArr);
adapter1 = new Custom_comment_Adapter(show_following);
following_userr_list.setAdapter(adapter);
mListView_COmment.setAdapter(adapter1);
editTextSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence s, int i, int i1, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
String s = editable.toString();
final_string = s.substring(1);
if (final_string.length() >= 1) {
following_userr_list.setVisibility(View.INVISIBLE);
mListView_COmment.setVisibility(View.VISIBLE);
filters(final_string);
}
}
private void filters(String text) {
ArrayList<String> filterdNames = new ArrayList<>();
for (String s : FollowingListValuesArr) {
if (s.toLowerCase().contains(text.toLowerCase())) {
filterdNames.add(s);
}
}
adapter.filterList(filterdNames);
adapter1.filterList(filterdNames);
}
});
}
}

You are getting error in this function. you need to check length of editable before process it.
#Override
public void afterTextChanged(Editable editable) {
String s = editable.toString();
final_string = s.substring(1);// when s is null
if (final_string.length() >= 1) {
following_userr_list.setVisibility(View.INVISIBLE);
mListView_COmment.setVisibility(View.VISIBLE);
filters(final_string);
}
}
When string is null you are doing s.substring
So add like below
#Override
public void afterTextChanged(Editable editable) {
if (editable.length() > 0) {
String s = editable.toString();
final_string = s.substring(1);
following_userr_list.setVisibility(View.INVISIBLE);
mListView_COmment.setVisibility(View.VISIBLE);
filters(final_string);
}
}

I think You should check the length before going through your logic.
#Override
public void afterTextChanged(Editable editable) {
if(editable.length()>0){
String s = editable.toString();
final_string = s.substring(1);
if (final_string.length() >= 1) {
following_userr_list.setVisibility(View.INVISIBLE);
mListView_COmment.setVisibility(View.VISIBLE);
filters(final_string);
}
}
}

Related

In recylerview the edittext the values are repeating when fetched through the interface

Recylerview
#Override
public void onBindViewHolder(#NonNull CustomListview.ViewHolder holder, int position) {
holder.Sno.setText(""+(position+1));
//remove colth unwanted characters
String cloth = list.get(position).getCloth();
String withoutFirstCharacter = cloth.substring(2,cloth.length()-1); // index starts at zero
holder.Cloth.setText(""+withoutFirstCharacter);
holder.qty.setText(list.get(position).getQuantity());
holder.QtyId.setText(list.get(position).getQtyId());
holder.Dis.setText(list.get(position).getDispatchedQty());
holder.deliverd is a edittext
if (list.get(position).getValue()==null){
holder.deliverd.setText("0");
list.get(position).setValue("0");
} else {
holder.deliverd.setText(String.valueOf(list.get(position).getValue()));
}
holder.deliverd.addTextChangedListener(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) {
if (TextUtils.isEmpty(holder.deliverd.getText()))
{
list.get(position).setValue("0");
} else {
list.get(position).setValue(holder.deliverd.getText().toString());
}
int a = Integer.parseInt(list.get(position).getValue());
//str is arraylist
str.add(Integer.parseInt(list.get(position).getValue()));
Log.i( "str",String.valueOf(str));
//interface through pass the values to mainactivity
dtInterface.onSetValues(str);
// activity.array_val();
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
Interface
public interface DataTransferInterface {
public void onSetValues(ArrayList<Integer> in );
}
MAinactivity interface implements and override the interface method
#Override
public void onSetValues(ArrayList<Integer> a )
{
HashMap<Integer, ArrayList<Integer>> hm=new HashMap<>();
hm.put(100,a);
//display hashmap element
Set s = hm.entrySet();
Iterator itr = s.iterator();
while (itr.hasNext()){
Map.Entry m = (Map.Entry)itr.next();
System.out.println(m.getKey()+":values:"+m.getValue());
Toast.makeText(this, "aaa"+m.getValue(),Toast.LENGTH_SHORT).show();
}
}
when i change the 1st,2nd,3rd edittext are correctly fetched the values one time. The problem is 4th,5th,etc edittext repeating the values 2 times and added to the arraylist. how to slove it.i tried more than 25days.. i attached the error below.
[![enter image description here][1]][1]
[enter link description here][1]
https://andriodretrofit.000webhostapp.com/WhatsAppVideo2020-02-03at83032PM.gif

How to replace particular word from edittext

I have one edittext: edittextmysite.
Now I want to provide default text, for example: "https://wwww.mysite.com/"
I have achieved it this as follows:
edittextmysite.setText("https://wwww.mysite.com/");
Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
edittextmysite.addTextChangedListener(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) {
if (!s.toString().contains("https://wwww.mysite.com/")) {
edittextmysite.setText("https://wwww.mysite.com/");
Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
}
}
});
So if anyone enters text it will automatically be appended to the default, like this: https://wwww.mysite.com/<Mytext>
Now what I want is if anyone writes something like this in edittext:
https://wwww.mysite.com/https://wwww.mysite.com/helloworld
or
https://wwww.mysite.com/wwww.mysite.com/helloworld
or
https://wwww.mysite.com/wwww.anyothersite.com/helloworld
that it will automatically convert it to the correct format, like this:
https://wwww.mysite.com/helloworld
How can I achieve this?
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().contains("https://wwww.mysite.com/")) {
String text = s.toString.subString(0, s.lastIndexOf("/"));
edittextmysite.setText(s.toString().replace(text, "https://wwww.mysite.com/");
Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
}
}
edittextmysite.addTextChangedListener(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) {
if(edittextmysite.getText().toString().length() == 0)
edittextmysite.setText("https://wwww.mysite.com/" + s.toString());
else
edittextmysite.append(s.toString());
}
});
Here is what i have tried.
private String str = "https://wwww.mysite.com/";
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().contains("https://wwww.mysite.com/")) {
edittextmysite.setText("https://wwww.mysite.com/");
Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
}
String s1 = s.toString();
String s2 = s1.substring(str.length());
if(s2.contains("/")) {
String s3 = s1.substring(str.length());
if (Patterns.WEB_URL.matcher(s3).matches()) {
// Valid url
edittextmysite.setText(s.toString().replace(s3, ""));
Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
}
}
}
This piece of code won't allow you to enter another URL and user can only enter string after URL as you explained above.
Thanks
Rather that editing the text afterwards, there are many nicer ways to accomplish this:
Place "https://example.com/" on the left of the edittext, then if you really have to, you can search the string for .com, www., etc. and remove it and the name they encapsulate using any algorithm found easily on the web. Then concatenate the strings.
Use a hint in the edittext.
here I have sharing complete working example. There is explanation along with it.
public class MainActivity extends AppCompatActivity implements TextWatcher {
String BASE_URL = "https://wwww.mysite.com";
EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*paste this editText --> https://wwww.mysite.com/https://wwww.mysite.com/helloworld <--*/
editText = findViewById(R.id.et);
editText.addTextChangedListener(this);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String text = s.toString().trim();
editText.removeTextChangedListener(this);
if (text.length() > 0) {
if (!text.contains(BASE_URL)) {
String tempText = BASE_URL +"/"+ text;
editText.setText(tempText); //setting text here
proceed(tempText); //sending here for further test, if pasted the link
} else {
proceed(text);
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
private void proceed(String text) {
String newText="";
String firstHalf = text.substring(0,text.lastIndexOf('/'));
String secondHalf = text.substring(text.lastIndexOf('/',(text.length()-1)));
String[] words = firstHalf.split("/"); //Split the word from String
for (int i = 0; i < words.length; i++){ //Outer loop for Comparison
if (words[i] != null) {
for (int j = i + 1; j < words.length; j++){ //Inner loop for Comparison
if (words[i].equals(words[j])) //Checking for both strings are equal
words[j] = null; //Delete the duplicate words
}
}
}
//Displaying the String without duplicate words{
for (int k = 0; k < words.length; k++){
if (words[k] != null)
newText=newText+words[k];
}
StringBuffer formattedText = new StringBuffer((newText+secondHalf));
formattedText.insert(6,"//"); //length of https;//
editText.setText(formattedText);
//attaching textwatcher again
editText.addTextChangedListener(this);
//moving cusor pointer to the end point
editText.setSelection(editText.getText().toString().length());
}
}
You should fix the prefix text into EditText which can not be editable and user only can edit the text after base-url (like after https://wwww.mysite.com/ ).
So you should follow these steps
Prefix the base url to EditText and make it un-editable
Let user enter sub part of the url
Validate input with Patterns.WEB_URL.matcher(inputUrl).matches() for valid url. You can add this validation on TextChange of EditText or on click of a button.
Below is a custom EditText code which you can use directly
public class UrlEditText extends AppCompatEditText {
float mLeftPadding = -1;
public UrlEditText(Context context) {
super(context);
}
public UrlEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UrlEditText(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
initPrefix();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
String prefix = (String) getTag();
canvas.drawText(prefix, mLeftPadding,
getLineBounds(0, null), getPaint());
}
private void initPrefix() {
if (mLeftPadding == -1) {
String prefix = (String) getTag();
float[] widths = new float[prefix.length()];
getPaint().getTextWidths(prefix, widths);
float textWidth = 0;
for (float w : widths) {
textWidth += w;
}
mLeftPadding = getCompoundPaddingLeft();
setPadding((int) (textWidth + mLeftPadding),
getPaddingRight(), getPaddingTop(),
getPaddingBottom());
}
}
}
and in layout xml file, it would be like
<com.path_of_custom_view.UrlEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="https://wwww.mysite.com/"
android:text="helloworld" />
Instead of using android:tag you can define custom attribute for this edittext.
And for input validation you can validate it like
String enteredUrl = textField.getText().toString();
if (Patterns.WEB_URL.matcher(enteredUrl).matches()) {
// Valid url
} else {
// Invalid url
}
You can Just store it as String and than simply String newReplacedString = stringtoReplace.replace("Phrase To Replace", "WHAT TO REPLACE WITH");
This one works for me, I hope this will work for you too.
#Override
public void afterTextChanged(Editable s) {
String text = edittextmysite.getText().toString();
String URL = "https://www.example.com/";
if (text.contains(URL)) {
String url = getUrl(URL, text);
if (!text.equals(url)) {
edittextmysite.setText(url);
edittextmysite.setSelection(url.length());
}
} else {
String tempUrl = URL + text;
String url = getUrl(URL, tempUrl);
if (!tempUrl.equals(url)) {
edittextmysite.setText(url);
edittextmysite.setSelection(url.length());
} else if (!text.contains(URL)) {
edittextmysite.setText(URL);
edittextmysite.setSelection(URL.length());
}
}
}
private String getUrl(String URL, String text) {
String urls[] = text.split("(?<!/)/(?!/)");
Log.v(TAG, Arrays.toString(urls));
String lastWord = urls[urls.length - 1];
String lastChar = text.substring(text.length() - 1);
if (lastChar.equals("/"))
lastWord = lastWord.concat(lastChar);
for (String url : urls) {
url = url.concat("/");
if (Patterns.WEB_URL.matcher(url).matches()) {
if (url.equals(URL)) {
if (!lastWord.contains("/"))
return url + lastWord;
else return text;
}
}
}
return URL;
}
In this code I tried your inputs, and its working.
It's not an elegant solution and I suggest you to use alternative UX for what you are trying to do entirely but if you really want to pursue this way then try the following code in your TextWatcher,
final String baseString="https://wwww.mysite.com/";
#Override
public void afterTextChanged(Editable s) {
if(!s.toString().contains(baseString)){
editText.setText(baseString+s.toString());
editText.setSelection(editText.length());
}else {
String regex = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&##/%?=~_|!:,.;]*[-a-zA-Z0-9+&##/%=~_|]";
Pattern pattern=Pattern.compile(regex);
String subStr=s.toString().substring(baseString.length());
Matcher matcher= pattern.matcher(subStr);
if(matcher.matches()){
editText.setText(baseString+subStr.replaceAll(regex,""));
editText.setSelection(editText.length());
}else if(subStr.contains("https:")){
editText.setText(baseString+subStr.replace("https:",""));
editText.setSelection(editText.length());
}else if(subStr.contains("www.")){
editText.setText(baseString+subStr.replace("www.",""));
editText.setSelection(editText.length());
}else if(subStr.contains(".")){
editText.setText(baseString+subStr.replaceAll("\\.",""));
editText.setSelection(editText.length());
}else if(subStr.contains("//")){
editText.setText(baseString+subStr.replaceAll("//",""));
editText.setSelection(editText.length());
}else if(subStr.contains(":")){
editText.setText(baseString+subStr.replaceAll(":",""));
editText.setSelection(editText.length());
}
}
}
Once user starts typing, it sets our base string in the edittext and forces
user not to write anything that can be a part of uri. One important thing to consider when user is trying to hit backspace, this is taken care of using the special condition and user won't be able to remove base string once he/she starts typing.
Note: This solution can be optimized as well
Answer
You can set edittext text to not remove by user. So the predefined text will stay with ediitext and automatically append the new text.
Try this:
private EditText et;
private String str_value = "http://example.com/";
private String added_str;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = findViewById(R.id.edittext);
et.setText(str_value);
et.setSelection(str_value.length());
et.addTextChangedListener(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) {
if(start == str_value.length() - 1)
{
et.setText(str_value);
et.setSelection(str_value.length());
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
Edited
If you want elimnate the domain name after user entered in the edittext. You can try below code
#Override
public void afterTextChanged(Editable s) {
if(s.length() > str_value.length()) {
added_str = s.toString().substring(str_value.length(), s.length()); //this will get text after predefined text.
if(Patterns.DOMAIN_NAME.matcher(added_str).matches() || added_str.contains("http:"))
{
et.setText(str_value);
et.setSelection(str_value.length());
}
}
}

How to validate a input field and prevent Dialog dismissing

In my application I extend the Dialog class to get user input for each field and now I want to validate them.
public abstract class EditDialogHelper extends Dialog implements android.view.View.OnClickListener {
private Context context;
private String title;
private String field;
private String positive;
private String negative;
private EditText etField;
private TextView tvCount;
private int characterCount;
public EditDialogHelper(Context context, String title, String field, String positive, String negative, int characterCount) {
super(context);
this.context = context;
this.title = title;
this.field = field;
this.positive = positive;
this.negative = negative;
this.characterCount = characterCount;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_edit_view);
TextView tvTitle = (TextView) findViewById(R.id.tvTitle);
etField = (EditText) findViewById(R.id.etField);
tvCount = (TextView) findViewById(R.id.tvInputCount);
Button btnConfirmationOk = (Button) findViewById(R.id.btnPositive);
Button btnConfirmationCancel = (Button) findViewById(R.id.btnNegative);
final TextWatcher 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) {
tvCount.setText(String.valueOf(characterCount - s.length()));
}
#Override
public void afterTextChanged(Editable s) {
}
};
etField.addTextChangedListener(textWatcher);
tvTitle.setText(title);
etField.setText(field);
etField.setFilters(new InputFilter[]{new InputFilter.LengthFilter(characterCount)});
btnConfirmationOk.setOnClickListener(this);
btnConfirmationCancel.setOnClickListener(this);
}
public String getValue() {
return etField.getText().toString().trim();
}
private boolean validateInputs(String value) {
boolean valid = false;
if (value != null && !(value.equals(""))) {
valid = true;
} else {
etField.setError("This can't be left empty");
}
return valid;
}
}
Once the dialog opens up I want it to be validated once the btnConfirmationOk is clicked and if the field is empty, it should be prevented from dismissing the dialog while showing the error.
Where should I use this validateInputs method and in which way it should be modified.
Answer is quite simple i guess
#Override
void onClick(View view) {
if (view.getId == R.id.btnPositive) {
boolean valid = validate("my string");
if(valid) {
// do stuff
dissmis();
}
} else {
dissmis();
}
}
But in my oppinion you should set different listeners to your possitive and negative buttons, instead of tracking everything with EditDialogHelper class.
this could be done like this.
button.setOnClickListener(new OnClickListener {
#Override
void onClick(View v) {
}
});
p.s. I wrote everything from my head so this could contain compilation errors.

How can i fix java.lang.IndexOutOfBoundsException: Invalid index in ArrayList on Android [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 5 years ago.
In my application I want get some list from server, and show this list into ChipCloud. ChipCloud has Tag library. Library Link : https://github.com/adroitandroid/ChipCloud
.I write below code but when run application when click on items show me below error :
java.lang.IndexOutOfBoundsException: Invalid index 11, size is 6
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.example.com.Activities.FullSearchMini$2$5.chipSelected(FullSearchMini.java:286)
at com.adroitandroid.chipcloud.ChipCloud.chipSelected(ChipCloud.java:253)
at com.adroitandroid.chipcloud.Chip.onClick(Chip.java:138)
at android.view.View.performClick(View.java:4764)
at android.view.View$PerformClick.run(View.java:19844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5349)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
My Codes :
public class FullSearchMini extends AppCompatActivity {
#BindView(R.id.miniFullSearch_toolbarText)
EditText fullSearchMini_headerText;
#BindView(R.id.fullSearchMini_celebritiesRecyclerView)
RecyclerView fullSearchMini_celebritiesRecyclerView;
#BindView(R.id.miniFullSearch_movieRecyclerView)
RecyclerView miniFullSearch_movieRecyclerView;
#BindView(R.id.miniFullSearch_SeriesRecyclerView)
RecyclerView miniFullSearch_SeriesRecyclerView;
#BindView(R.id.miniFullSearch_UserRecyclerView)
RecyclerView miniFullSearch_UserRecyclerView;
#BindViews({R.id.fullSearchMini_celebritiesHeaderLay, R.id.miniFullSearch_movieHeaderLay, R.id.miniFullSearch_SeriesHeaderLay,
R.id.miniFullSearch_UserHeaderLay})
List<RelativeLayout> miniSearchLayouts;
#BindViews({R.id.celebritiesLine, R.id.moviesLine, R.id.SeriesLine})
List<RelativeLayout> miniSearchLines;
#BindView(R.id.fullSearchMini_didYouMeanLay)
RelativeLayout fullSearchMini_didYouMeanLay;
#BindView(R.id.miniFullSearch_LoadLay)
RelativeLayout miniFullSearch_LoadLay;
#BindView(R.id.fullSearchMini_chipCloud)
ChipCloud fullSearchMini_chipCloud;
#BindView(R.id.fullSearchMini_EmptyLay)
RelativeLayout fullSearchMini_EmptyLay;
#BindView(R.id.empty_text)
TextView empty_text;
#BindView(R.id.miniFullSearch_LoadProgress)
ProgressBar miniFullSearch_LoadProgress;
private Context context;
private MiniSearchCelebritiesAdapter celebritiesAdapter;
private MiniSearchMoviesAdapter moviesAdapter;
private MiniSearchSeriesAdapter seriesAdapter;
private MiniSearchUsersAdapter userAdapter;
private List<Celebrity> celebritiesModel = new ArrayList<>();
private List<Movie> moviesModel = new ArrayList<>();
private List<Series> seriesModel = new ArrayList<>();
private List<User> userModel = new ArrayList<>();
private String searchKey, chipKey;
private List<String> cloudChipList = new ArrayList<>();
private String[] mostlyMatchedKeywordsStrings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mini_full_search);
// Initialize
ButterKnife.bind(this);
context = this;
//Set Color to progressBar
miniFullSearch_LoadProgress.getIndeterminateDrawable().setColorFilter(Color.parseColor("#ff8d00"),
android.graphics.PorterDuff.Mode.SRC_ATOP);
celebritiesAdapter = new MiniSearchCelebritiesAdapter(context, celebritiesModel);
moviesAdapter = new MiniSearchMoviesAdapter(context, moviesModel);
seriesAdapter = new MiniSearchSeriesAdapter(context, seriesModel);
userAdapter = new MiniSearchUsersAdapter(context, userModel);
initRecyclerView(fullSearchMini_celebritiesRecyclerView);
initRecyclerView(miniFullSearch_movieRecyclerView);
initRecyclerView(miniFullSearch_SeriesRecyclerView);
initRecyclerView(miniFullSearch_SeriesRecyclerView);
initRecyclerView(miniFullSearch_UserRecyclerView);
// TextWatcher
fullSearchMini_headerText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
searchKey = editable.toString();
if (searchKey.length() > 1) {
getData(searchKey);
}
}
});
}
private void getData(String key) {
FullSearchSendData sendData = new FullSearchSendData();
sendData.setKey(key);
sendData.setLoadImages(true);
sendData.setSearchInCelebrities(true);
sendData.setSearchInMovies(true);
sendData.setSearchInSeries(true);
sendData.setSearchInEpisodes(false);
sendData.setSearchInUsers(true);
sendData.setPageIndex(1);
sendData.setPageSize(4);
sendData.setMaxDistance(1);
miniFullSearch_LoadLay.setVisibility(View.VISIBLE);
InterfaceApi api = ApiClient.getClient().create(InterfaceApi.class);
Call<FullSearchResponse> call = api.getFullSearch(sendData);
call.enqueue(new Callback<FullSearchResponse>() {
#Override
public void onResponse(Call<FullSearchResponse> call, Response<FullSearchResponse> response) {
FullSearchResponse searchResponse = response.body();
if (searchResponse.getData().getCelebrities() != null) {
if (searchResponse.getData().getCelebritiesCount() > 0) {
celebritiesModel.clear();
celebritiesModel.addAll(searchResponse.getData().getCelebrities());
celebritiesAdapter.notifyDataSetChanged();
fullSearchMini_celebritiesRecyclerView.setAdapter(celebritiesAdapter);
miniSearchLayouts.get(0).setVisibility(View.VISIBLE);
miniSearchLines.get(0).setVisibility(View.VISIBLE);
fullSearchMini_celebritiesRecyclerView.setVisibility(View.VISIBLE);
miniSearchLayouts.get(0).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, FullSearch.class);
intent.putExtra(ExtraContains.FULL_SEARCH_TEXT.name(), searchKey);
startActivity(intent);
}
});
} else {
miniSearchLayouts.get(0).setVisibility(View.GONE);
miniSearchLines.get(0).setVisibility(View.GONE);
fullSearchMini_celebritiesRecyclerView.setVisibility(View.GONE);
}
}
if (searchResponse.getData().getMovies() != null) {
if (searchResponse.getData().getMoviesCount() > 0) {
moviesModel.clear();
moviesModel.addAll(searchResponse.getData().getMovies());
moviesAdapter.notifyDataSetChanged();
miniFullSearch_movieRecyclerView.setAdapter(moviesAdapter);
miniSearchLayouts.get(1).setVisibility(View.VISIBLE);
miniSearchLines.get(1).setVisibility(View.VISIBLE);
miniFullSearch_movieRecyclerView.setVisibility(View.VISIBLE);
miniSearchLayouts.get(1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, FullSearch.class);
intent.putExtra(ExtraContains.FULL_SEARCH_TEXT.name(), searchKey);
startActivity(intent);
}
});
} else {
miniSearchLayouts.get(1).setVisibility(View.GONE);
miniSearchLines.get(1).setVisibility(View.GONE);
miniFullSearch_movieRecyclerView.setVisibility(View.GONE);
}
}
if (searchResponse.getData().getSeries() != null) {
if (searchResponse.getData().getSeriesCount() > 0) {
seriesModel.clear();
seriesModel.addAll(searchResponse.getData().getSeries());
seriesAdapter.notifyDataSetChanged();
miniFullSearch_SeriesRecyclerView.setAdapter(seriesAdapter);
miniSearchLayouts.get(2).setVisibility(View.VISIBLE);
miniSearchLines.get(2).setVisibility(View.VISIBLE);
miniFullSearch_SeriesRecyclerView.setVisibility(View.VISIBLE);
miniSearchLayouts.get(2).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, FullSearch.class);
intent.putExtra(ExtraContains.FULL_SEARCH_TEXT.name(), searchKey);
startActivity(intent);
}
});
} else {
miniSearchLayouts.get(2).setVisibility(View.GONE);
miniSearchLines.get(2).setVisibility(View.GONE);
miniFullSearch_SeriesRecyclerView.setVisibility(View.GONE);
}
}
if (searchResponse.getData().getUsers() != null) {
if (searchResponse.getData().getUsersCount() > 0) {
userModel.clear();
userModel.addAll(searchResponse.getData().getUsers());
userAdapter.notifyDataSetChanged();
miniFullSearch_UserRecyclerView.setAdapter(userAdapter);
miniSearchLayouts.get(3).setVisibility(View.VISIBLE);
miniFullSearch_UserRecyclerView.setVisibility(View.VISIBLE);
miniSearchLayouts.get(3).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, FullSearch.class);
intent.putExtra(ExtraContains.FULL_SEARCH_TEXT.name(), searchKey);
startActivity(intent);
}
});
} else {
miniSearchLayouts.get(3).setVisibility(View.GONE);
miniFullSearch_UserRecyclerView.setVisibility(View.GONE);
}
}
// Did you mean
String[] mostlyMatchedKeywordsStrings = searchResponse.getData().getMostlyMatchedKeywordsText();
cloudChipList.clear();
for (int i = 0; i < mostlyMatchedKeywordsStrings.length; i++) {
cloudChipList.add(mostlyMatchedKeywordsStrings[i]);
if (i >= mostlyMatchedKeywordsStrings.length - 2) {
fullSearchMini_didYouMeanLay.setVisibility(View.VISIBLE);
fullSearchMini_chipCloud.addChip(mostlyMatchedKeywordsStrings[i]);
Log.e("searchKeys", mostlyMatchedKeywordsStrings[i]);
}
}
fullSearchMini_chipCloud.setChipListener(new ChipListener() {
#Override
public void chipSelected(int i) {
chipKey = cloudChipList.get(i);
Intent intent = new Intent(context, FullSearch.class);
intent.putExtra(ExtraContains.FULL_SEARCH_TEXT.name(), chipKey);
startActivity(intent);
}
#Override
public void chipDeselected(int i) {
}
});
if (searchResponse.getData().getCelebrities().size() == 0 && searchResponse.getData().getSeries().size() == 0
&& searchResponse.getData().getMovies().size() == 0 && searchResponse.getData().getUsers().size() == 0) {
fullSearchMini_EmptyLay.setVisibility(View.VISIBLE);
empty_text.setText(context.getResources().getString(R.string.noResultFound) + " for : " + searchKey);
} else {
fullSearchMini_EmptyLay.setVisibility(View.GONE);
}
miniFullSearch_LoadLay.setVisibility(View.GONE);
}
#Override
public void onFailure(Call<FullSearchResponse> call, Throwable t) {
miniFullSearch_LoadLay.setVisibility(View.GONE);
}
});
}
Show me above error for this line :
chipKey = cloudChipList.get(i);
How can I fix this error? Please help me my friend. I really need your help. please
In the error it says,
Invalid index 11, size is 6
That means the actual number of elements in your cloudChipList is only 6. That is, your searchResponse.getData().getMostlyMatchedKeywordsText(); function returns only 6 values and then its stored in the array list. But when you call the public void chipSelected(int i) function, if the value of i is more than 5 then it will show this java.lang.IndexOutOfBoundsException. If you have 6 values in your array list then you can only provide index value from 0 till 5. In your case the value of i in public void chipSelected(int i) is 11 and so the error.
The index for schipSelected method is being calculated in the ChipCloud class.
fullSearchMini_chipCloud.setChipListener(new ChipListener() {
#Override
public void chipSelected(int i) { //This is callback from ChipCloud class
chipKey = cloudChipList.get(i);
}
#Override
public void chipDeselected(int i) {
}
});
The fullSearchMini_chipCloud layout is being added duplicate chips. You need to clear the existing childs before adding new chips.
After clearing the list with
cloudChipList.clear();
Remove existing childs with
fullSearchMini_chipCloud.removeAllViews()

Show the Listview only when the search string is entered

I want the listView to be displayed only when a search string is inserted in the EditText. Below is my code...Please help me I would be highly obliged...
public class MainActivity extends AppCompatActivity {
private ListView mSearchNFilterLv;
private EditText mSearchEdt;
private ArrayList<String> mStringList;
private ValueAdapter valueAdapter;
private TextWatcher mSearchTw;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
initData();
valueAdapter = new ValueAdapter(mStringList, this);
mSearchNFilterLv.setAdapter(valueAdapter);
mSearchEdt.addTextChangedListener(mSearchTw);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
private void initData() {
mStringList = new ArrayList<String>();
mStringList.add("one");
mStringList.add("two");
mStringList.add("three");
mStringList.add("four");
mStringList.add("five");
mStringList.add("six");
mStringList.add("seven");
mStringList.add("eight");
mStringList.add("nine");
mStringList.add("ten");
mStringList.add("eleven");
mStringList.add("twelve");
mStringList.add("thirteen");
mStringList.add("fourteen");
mSearchTw = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
valueAdapter.getFilter().filter(s);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
if(mSearchEdt.getVisibility() != View.VISIBLE)
mSearchEdt.setVisibility(View.VISIBLE);
}
};
}
private void initUI() {
mSearchNFilterLv = (ListView) findViewById(R.id.list_view);
mSearchEdt = (EditText) findViewById(R.id.txt_search);
}
}
You can use the code below:
mSearchTw = 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) {
if (s != null && s.toString().trim().length() > 0) {
mSearchNFilterLv.setVisibility(View.VISIBLE);
} else {
mSearchNFilterLv.setVisibility(View.GONE);
}
}
#Override public void afterTextChanged(Editable s) {
}
};
This will show the ListView when there is an entered text (while entering text to EditText) and if text has 1 or more characters.
If you want ListView to be changed only when the insertion is over move the given code inside onTextChanged to afterTextChanged
PS: You can use the same structure with SearchView instead of EditText with query listeners.
Updated
You can use below code to hide ListView initially:
private void initUI() {
mSearchNFilterLv = (ListView) findViewById(R.id.list_view);
mSearchEdt = (EditText) findViewById(R.id.txt_search);
mSearchNFilterLv.setVisibility(View.GONE);
}

Categories

Resources