this is recyclerview where I am selecting the option and saving in activity but I want to select
only one option but it is selecting multiple this is the problem, and how to apply mainIndex I am handling in activity and then notify adapter.
#Override
public void onBindViewHolder(#NonNull final ExamQuestionViewHolder holder, int i) {
final ExamQuestionsOptionsItem item = itemList.get(i);
if (!TextUtils.isEmpty(item.getOption()) && item.getOption() != null){
holder.tvOption.setText(item.getOption());
}else {
holder.tvOption.setText("");
}
holder.rlMain.setSelected(item.isSelected());
holder.rlMain.setBackground(ContextCompat.getDrawable(context,
item.isSelected() ? R.drawable.preference_bg_selected : R.drawable.rect_box_white));
holder.rlMain.setAlpha(0.6f);
holder.tvOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.rlMain.performClick();
}
});
holder.tvOption.setTextColor(ContextCompat.getColor(context,
item.isSelected() ? R.color.colorPrimary : R.color.font_color));
selecting options
holder.rlMain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isClickable)return;
holder.rlMain.setAlpha(0.6f);
item.setSelected(!item.isSelected());
holder.tvOption.setTextColor(ContextCompat.getColor(context,
item.isSelected() ? R.color.colorPrimary : R.color.font_color));
holder.rlMain.setBackground(ContextCompat.getDrawable(context,
item.isSelected() ? R.drawable.preference_bg_selected :
R.drawable.rect_box_white));
if (item.isSelected()){
selectedOptionList.add(item.getOptionId());
}else {
if (selectedOptionList != null)
selectedOptionList.remove(item.getOptionId());
}
if (selectedOptionList != null)
selectedOptionListner.selectedOptionList(selectedOptionList);
}
});
}
activity calling questions, answer options are appearing in recyclerview and question is in activity textview
protected void fetchQuestions() {
viewsDisable();
Call<ExamQuestionResponse> call =
ApiClient.getInstance().getMainApi().getExamQuestions(Util.getHeaderMap(token), examId);
call.enqueue(new Callback<ExamQuestionResponse>() {
#Override
public void onResponse(Call<ExamQuestionResponse> call, Response<ExamQuestionResponse>
response) {
viewsEnable();
if (response.body() != null) {
ExamQuestionResponse mResponse = response.body();
if (mResponse.isStatus()) {
questionList = mResponse.getData();
if (questionList != null && questionList.size() > 0) {
binding.tvQuestion.setText(questionList.get(mainIndex).getQuestion());
adapter = new ExamQuestionAdapter(ExamQuestionsActivity.this, optionList,
new ExamQuestionAdapter.RecyclerViewClickListener() {
#Override
public void recyclerViewListClicked(View v, int position) {
//adapter.notifyDataSetChanged();
}
}, new ExamQuestionAdapter.SelectedOptionList() {
#Override
public void selectedOptionList(ArrayList<String> list) {
selectedOptionList = list;
}
});
binding.recyclerview.setAdapter(adapter);
} else {
dataNotFound();
}
} else {
dataNotFound();
}
} else {
dataNotFound();
}
}
#Override
public void onFailure(Call<ExamQuestionResponse> call, Throwable t) {
viewsEnable();
}
});
}
// next button in activity, question is updating because i have mainIndex but option are in
// recyclerview they are not updating
binding.tvNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mainIndex++;
binding.tvQuestion.setText("");
binding.tvQuestion.setText(questionList.get(mainIndex).getQuestion());
adapter.notifyDataSetChanged();
}
});
I have solved the question I was not using proper indexes to move the index on button click.
I have used index++ or index-- on next and previous button click.
protected void showNextQuestion() {
boolean isAnyItemSelect = false;
List<ExamQuestionsOptionsItem> optionsItems =
examQuestionDataItemList.get(currentIndex).getOptions();
prefConfig.saveOptionsItem(optionsItems);
for (int i = 0; i < optionsItems.size(); i++) {
if (optionsItems.get(i).isSelected()) {
isAnyItemSelect = true;
break;
}
}
if (!isAnyItemSelect) {
Toast.makeText(this, "Please select any answer before proceeding",
Toast.LENGTH_SHORT).show();
return;
}
if (currentIndex == questionListSize - 1) {
showFinishAlert(this.getString(R.string.exam_going_to_finish));
} else {
currentIndex++;
prefConfig.writeRecoverIndex(currentIndex);
if(isReview && !examQuestionDataItemList.get(currentIndex).isReview() )
{
showNextQuestion();
return;
}
setQuestions();
}
}
Related
I'm trying to catch onMeetingStatusChanged event. But for my case, the onMeetingStatusChanged is sometimes invoked, not all the time. Below is my implemented code:
#Override
protected void onCreate(Bundle savedInstanceState) {
registerListener();
InitAuthSDKHelper.getInstance().initSDK(this, new InitAuthSDKCallback() {
#Override
public void onZoomSDKInitializeResult(int i, int i1) {
}
#Override
public void onZoomAuthIdentityExpired() {
}
});
}
private void registerListener() {
ZoomSDK zoomSDK = ZoomSDK.getInstance();
MeetingService meetingService = zoomSDK.getMeetingService();
if (meetingService != null) {
meetingService.addListener(this);
}
}
#Override
public void onMeetingStatusChanged(MeetingStatus meetingStatus,
int errorCode,
int internalErrorCode) {
LogD.d(TAG, String.valueOf(meetingStatus));
if (meetingStatus == MeetingStatus.MEETING_STATUS_IDLE) {
layout_zoom_loading.setVisibility(View.VISIBLE);
} else {
layout_zoom_loading.setVisibility(View.GONE);
}
if(meetingStatus == MeetingStatus.MEETING_STATUS_FAILED
&& errorCode == MeetingError.MEETING_ERROR_CLIENT_INCOMPATIBLE) {
Toast.makeText(this, "Version of ZoomSDK is too low!", Toast.LENGTH_LONG).show();
}
}
public void joinMeeting(String meetingNo, String meetingPassword) {
ZoomSDK zoomSDK = ZoomSDK.getInstance();
if (!zoomSDK.isInitialized()) {
Toast.makeText(this, getString(R.string.msg_zoom_init_fail), Toast.LENGTH_LONG).show();
return;
}
JoinMeetingHelper.getInstance().joinMeetingWithNumber(this, meetingNo, meetingPassword);
}
I see the cause of this problem. We need to separate the initSDK method to BaseActivity class. So when user forward into the next Activity which runs Zoom meeting, onMeetingStatusChanged always be invoked.
I am using FlexboxLayout for showing chips in android but stuck at UI Where I want to show number of chips count at the end of second line as per below screenshot
As per above design I want to show chips until second line and the chips that not fit in second line should increase chip count at the end of chips
What I have check is
1- FlexboxLayout setMaxLine(2); But in this case UI only two line draw and second line is strech
2- FlexboxLayout getFlexLineInternel() - this API gives wrong result. Count of line is increases after 1 item added in the line then it gives getFlexLineInternel().size() == 2 it means view is already added in third line but I want to restrict only on 2 lines.
3- Try with Material Chip and ChipGroup - It didn't given me number of lines draw in chipGroup
4- Try with Flowlayout similar as ChipGroup. Didn't given me number of lines draw by layout so that I can show count at end of second line
Please give me suggestion what is helpful in my situation
Here is my code
activity_search_label.xml
<com.google.android.flexbox.FlexboxLayout
android:id="#+id/assetLabelsContainer"
android:layout_width="match_parent"
android:layout_marginLeft="#dimen/size_16"
android:layout_marginRight="#dimen/size_16"
android:layout_height="wrap_content"
app:flexWrap="wrap"/>
LabelSearchActivity.java
public class LabelSearchActivity extends SearchActivity {
#BindView(R.id.assetLabelsContainer)
public FlexboxLayout assetLabelsContainer;
private int COUNTER_LABEL_ID = -1;
private ArrayList<LabelModelParcelableItem> selectedLabels;
private ArrayList<LabelModelParcelableItem> visibleSelectedList;
private CompositeDisposable disposables;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
clearLabelList();
showSelectedLabel();
}
public void hideSearchTitleCountView() {
if (null != searchTitle) {
searchTitle.setVisibility(View.GONE);
}
}
private void clearLabelList() {
selectedLabels = new ArrayList<>();
visibleSelectedList = new ArrayList<>();
assetLabelsContainer.getFlexLinesInternal().clear();
assetLabelsContainer.removeAllViews();
}
private void showSelectedLabel() {
if (getIntent() != null) {
Bundle bundle = getIntent().getExtras();
if (bundle.getParcelableArrayList(SELECTED_LABEL_ITEMS) != null) {
ArrayList<LabelModelParcelableItem> selectedLabels = bundle
.getParcelableArrayList(SELECTED_LABEL_ITEMS);
showLabelList(selectedLabels);
}
}
}
public void addViewToFlex(final LabelModelParcelableItem labelModelParcelableItem) {
if (!selectedLabels.contains(labelModelParcelableItem)) {
selectedLabels.add(labelModelParcelableItem);
final View view = getChipView(labelModelParcelableItem);
if (shouldShowCount()) {
View countView = getCounterView();
if (null != countView) {
LabelModelParcelableItem tag = (LabelModelParcelableItem) countView.getTag();
LabelModelParcelableItem updatedTag =
new LabelModelParcelableItem(
tag.getLabelId(), String.valueOf(getInvisibleItemCount()), tag.getAssetCount());
TextView textView = (TextView) countView.findViewById(R.id.labelNameText);
textView.setText(" + " + updatedTag.getLabelName());
countView.setTag(updatedTag);
assetLabelsContainer.requestLayout();
} else {
addCounterView();
}
} else {
visibleSelectedList.add(labelModelParcelableItem);
assetLabelsContainer.addView(view);
}
}
}
public int getInvisibleItemCount() {
ArrayList<LabelModelParcelableItem> itemList = new ArrayList<>(selectedLabels);
itemList.removeAll(visibleSelectedList);
return itemList.size();
}
private void addCounterView() {
final View view =
LayoutInflater.from(LabelSearchActivity.this)
.inflate(R.layout.label, assetLabelsContainer, false);
LabelModelParcelableItem item =
new LabelModelParcelableItem(
COUNTER_LABEL_ID, String.valueOf(getInvisibleItemCount()), COUNTER_LABEL_ID);
view.setTag(item);
TextView textView = (TextView) view.findViewById(R.id.labelNameText);
textView.setText(" + " + item.getLabelName());
view.setOnClickListener(v -> showLabelContainerScreen(getSelectedLabels()));
if (getInvisibleItemCount() > 0) {
assetLabelsContainer.addView(view);
}
}
public View getChipView(final LabelModelParcelableItem item) {
final View view =
LayoutInflater.from(LabelSearchActivity.this)
.inflate(R.layout.label, assetLabelsContainer, false);
TextView textView = (TextView) view.findViewById(R.id.labelNameText);
textView.setText(item.getLabelName());
view.setOnClickListener(v -> removeViewFormFlex(view, item));
return view;
}
private boolean shouldShowCount() {
if (assetLabelsContainer.getFlexLinesInternal().size() > 2) {
return true;
}
return false;
}
private void updatedLabelAfterRemove() {
if (null != getCounterView()) {
if (getInvisibleItemCount() > 0) {
ArrayList<LabelModelParcelableItem> itemList = new ArrayList<>(selectedLabels);
itemList.removeAll(visibleSelectedList);
Collections.sort(itemList, (o1, o2) -> o2.getLabelName().compareTo(o1.getLabelName()));
if (!itemList.isEmpty()) {
addViewAfterRemove(itemList.get(0));
}
} else {
assetLabelsContainer.removeView(getCounterView());
}
}
}
private void addViewAfterRemove(LabelModelParcelableItem item) {
final View labelView = getChipView(item);
View countView = getCounterView();
if (countView != null) {
assetLabelsContainer.removeView(countView);
visibleSelectedList.add(item);
assetLabelsContainer.addView(labelView);
addCounterView();
} else {
visibleSelectedList.add(item);
assetLabelsContainer.addView(labelView);
}
}
private View getCounterView() {
View countView =
assetLabelsContainer.getFlexItemAt(assetLabelsContainer.getFlexItemCount() - 1);
if (null != countView) {
LabelModelParcelableItem item = (LabelModelParcelableItem) countView.getTag();
if (item != null && item.getLabelId() == -1) {
return countView;
}
}
return null;
}
private void showLabelList(ArrayList<LabelModelParcelableItem> selectedLabels) {
for (LabelModelParcelableItem item : selectedLabels) {
addViewToFlex(item);
assetLabelsContainer.post(() -> assetLabelsContainer.requestLayout());
}
}
public void addSelectedLabel(Parcelable label) {
addViewToFlex((LabelModelParcelableItem) label);
}
public ArrayList<LabelModelParcelableItem> getSelectedLabels() {
return selectedLabels;
}
public List<Parcelable> getUpdatedLabelList(List<? extends Parcelable> newParcelableList) {
if (null != newParcelableList && !newParcelableList.isEmpty()) {
newParcelableList.removeAll(getSelectedLabels());
return new ArrayList<>(newParcelableList);
} else {
return new ArrayList<>();
}
}
public void labelUpdateList(List dataList) {
getSearchAdapter().clearAndUpdateList(dataList);
}
#Override
public void onBackButtonPressed() {
setActivityResult(getSelectedLabels());
}
public void setActivityResult(ArrayList<? extends Parcelable> searchableItem) {
setResult(RESULT_OK, new Intent().putParcelableArrayListExtra(SEARCH_RESULT, searchableItem));
super.onBackButtonPressed();
}
public void addDisposable(Disposable disposable) {
if (null == disposables) {
disposables = new CompositeDisposable();
}
disposables.add(disposable);
}
#Override
public void onDestroy() {
if (disposables != null && !disposables.isDisposed()) {
disposables.clear();
}
super.onDestroy();
}
private void showLabelContainerScreen(List<? extends Parcelable> labels) {
Intent intent = new Intent(this, ViewLabelsActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(
LabelSelectionActivity.ARGUMENT_KEY, (ArrayList<? extends Parcelable>) labels);
intent.putExtras(bundle);
startActivityForResult(intent, LabelSelectionActivity.VIEW_ALL_LABEL_CODE);
}
#Override
public void onBackPressed() {
if (!getSelectedLabels().isEmpty()) {
Intent intent = new Intent();
intent.putParcelableArrayListExtra(
SELECTED_LABEL_ITEMS, (ArrayList<? extends Parcelable>) getSelectedLabels());
setResult(Activity.RESULT_OK, intent);
} else {
this.finish();
}
super.onBackPressed();
}
#OnClick(R.id.navBarBack)
public void onBackButton() {
onBackPressed();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != LabelSelectionActivity.VIEW_ALL_LABEL_CODE) {
return;
}
if (data == null) {
return;
}
if (resultCode != RESULT_OK) {
return;
}
if (!data.hasExtra(SELECTED_LABEL_ITEMS)) {
return;
}
clearLabelList();
ArrayList<LabelModelParcelableItem> selectedLabels =
data.getParcelableArrayListExtra(SELECTED_LABEL_ITEMS);
showLabelList(selectedLabels);
updateAfterViewAllLabels(selectedLabels);
}
private void updateAfterViewAllLabels(ArrayList<LabelModelParcelableItem> labelsAfterRemoved) {
ArrayList<LabelModelParcelableItem> listOfRemovedLabels = new ArrayList<>(getSelectedLabels());
listOfRemovedLabels.removeAll(labelsAfterRemoved);
for (LabelModelParcelableItem item : labelsAfterRemoved) {
//removeViewFormFlex(item);
}
}
public void removeViewFormFlex(View view, LabelModelParcelableItem item) {
if (selectedLabels.remove(item)) {
if (selectedLabels.isEmpty()) {
assetLabelsContainer.removeAllViews();
} else {
visibleSelectedList.remove(item);
assetLabelsContainer.removeView(view);
}
updatedLabelAfterRemove();
Comparator<LabelModelParcelableItem> compareByName =
(o1, o2) -> o1.getLabelName().compareTo(o2.getLabelName());
getSearchAdapter().addLabelItemToList(item, compareByName);
}
}
}
As per above code it look like below image
try to measure the height of FlexboxLayout after each flexboxLayout.addView(view) and if the width increased that is mean you are in second line.
Halo, I have LoadMore RecyclerView in my app. it's work, but when i'm load more item, the recyclerview always keep showing the top of the list. I mean, it should be shown the last item loaded.
Anyone, would you like to help me? thanks.
my screenshoot :
1 - 5 is the first list loaded:
6 - 10 shown after scrolling the recyclerView, but after 6 - 10
loaded, recyclerView always keep showing the top of the list (1-5)
:
this is my code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_job_company);
//intent untuk nerima value namaAdver dan handling jika tdk ada list
TextView namaCompany = (TextView) findViewById(R.id.tv_companyname);
TextView emptyList = (TextView) findViewById(R.id.emptylist);
loading = (ProgressBar) findViewById(R.id.loading);
loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
Intent intentGet = getIntent();
companyName = intentGet.getStringExtra("namaCompany");
idComp = intentGet.getStringExtra("idCompany");
try {
compID = Integer.parseInt(idComp);
} catch (NumberFormatException nfe) {
}
namaCompany.setText(companyName);
setTitle(intentGet.getStringExtra("namaCompany"));
PaginationJobCompany(compID, pageNum);
recyclerView = (RecyclerView) findViewById(R.id.rv_job_company2);
recyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), null)); //untuk divider
}
private void PaginationJobCompany(final int compID, final int pageNumber) {
try {
loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
loading.setVisibility(View.GONE);
//authorization JWT pref_token berdasarkan string yg disimpan di preferenceManager pada class login.
Authorization = (PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(
getResources().getString(R.string.pref_token), ""));
//production
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(getResources().getString(R.string.base_url))
.addConverterFactory(GsonConverterFactory.create())
.build();
//assign variabel request ke class interface TabAdverRequest
final APIInterfaces request = retrofit.create(APIInterfaces.class);
Call<ReportJobModel> call = request.getReportPagination(compID, pageNum, length, Authorization); //ngirim ke API
call.enqueue(new Callback<ReportJobModel>() {
#Override
public void onResponse(Call<ReportJobModel> call, Response<ReportJobModel> response) {
loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
loading.setVisibility(View.GONE);
if (response.isSuccessful()) {
companyResult = response.body().getResult();
if (!companyResult.isEmpty()) {
company.addAll(companyResult);
for (int i = 0; i < companyResult.size(); i++) {
if (company.get(i).getCompanyID() == compID) {
jobItemResult = response.body().getResult().get(i).getJobs();
jobItem.addAll(jobItemResult);
}
}
}
else {
for (int j = 0; j < companyResult.size(); j++) {
if (company.get(j).getCompanyID() == compID) {
lastId = jobItem.size()-1;
}
}
}
adapter = new JobCompanyAdapter(jobItem, recyclerView);
recyclerView.setAdapter(adapter);
adapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore() {
//add null , so the adapter will check view_type and show progress bar at bottom
jobItem.add(null);
adapter.notifyItemInserted(jobItem.size() - 1);
loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
loading.setVisibility(View.GONE);
handler.postDelayed(new Runnable() {
#Override
public void run() {
jobItem.remove(jobItem.size() - 1);
adapter.notifyItemRemoved(jobItem.size());
loading.setVisibility(View.GONE);
pageNum++;
loading.setVisibility(View.GONE);
PaginationJobCompany(compID, pageNum);
adapter.notifyDataSetChanged();
}
}, 2000);
}
});
} else if (response.errorBody() != null) {
loading.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda!", Toast.LENGTH_LONG).show();
} else if (response.code() == 400) {
loading.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda!", Toast.LENGTH_LONG).show();
} else {
loading.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda! 1", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<ReportJobModel> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda! 1", Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda! 1", Toast.LENGTH_LONG).show();
}
}
Okay I'll assume that you already have an implementation of the EndlessScrollListener for the RecyclerView if not, I urge you check out this: https://gist.github.com/nesquena/d09dc68ff07e845cc622. Further to make your code more readable and adaptable, I would recommend that you use more encapsulation.
For example: Have a NetworkHandler that does the callbacks for you to the UI. Where you switch the UI behaviour accordingly. To do that you need a OnDataCallback interface.
// OnDataCallback.java
interface OnDataCallback<T> {
void onData(T data);
void onError(Throwable error);
}
// NetworkHandler.java
public class NetworkHandler<T> {
#Nullable
protected OnDataCallback<T> dataCallback;
protected int pageIndex = 0;
public void setDataCallback(OnDataCallback<T> dataCallback) {
this.dataCallback = dataCallback;
}
public void removeDataCallback() {
dataCallback = null;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
public void updatePageNumber() {
pageIndex++;
}
}
Create a RetrofitUtils class as a Singleton that could be used to creating the services.
public static class RetrofitUtils {
private static RetrofitUtils utils;
public static RetrofitUtils getInstance() {
if (utils == null) {
utils = new RetrofitUtils();
}
return utils;
}
private Retrofit retrofit;
public Retrofit getRetrofitInstance(){
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl("http://mybaseurl.api/v1/")
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
public JobService constructJobService(Class<JobService> uClass) {
return getRetrofitInstance().create(uClass);
}
public LoginService construcstLoginService(Class<LoginService> uClass) {
return getRetrofitInstance().create(uClass);
}
}
Then inherit the NetworkHandler and override the methods according to your specifications for example have a JobNetworkHandler that does the request and paging for you. Create custom Throwable classes to handle error more efficiently like in the example it is ErrorBodyThrowable. All that is left is you have to implement the callback and set UI in fragment or activity.
public class JobReportHandler extends NetworkHandler<ReportJobModel> {
int compID;
int length;
Authorization auth = AuthUtils.getAuth();
#Override
public void updatePageNumber() {
super.updatePageNumber();
fetchJobsModel(compID, length);
}
public void fetchJobsModel(int compID, int length) {
this.compID = compID;
this.length = length;
JobService request = RetrofitUtils.getInstance().constructJobService(JobService.class);
Call<ReportJobModel> call = request.getReportPagination(compID, pageIndex, length, auth); //ngirim ke API
call.enqueue(new Callback<JobModel>() {
#Override
public void onResponse(Call<JobModel> call, Response<JobModel> response) {
// manipulate data and pass the UI model
// that needs to be handled by the view
ReportJobModel reportJobModel = response.convertToReport();
if (dataCallback == null) return;
if (response.isSuccessful()) {
dataCallback.onData(reportJobModel);
} else if (response.errorBody() != null) {
dataCallback.onError(new ErrorBodyThrowable());
} else if (response.code() == 400) {
dataCallback.onError(new ApiError());
} else {
// do something else
}
}
#Override
public void onFailure(Call<ReportJobModel> call, Throwable t) {
if (dataCallback != null) {
dataCallback.onError(t);
}
}
});
}
public class ErrorBodyThrowable extends Throwable {
ErrorBodyThrowable() {
super("Gagal Memuat. Periksa Koneksi Anda!");
}
}
}
Note that updating the pageIndex automatically triggers the network call so you avoid writing redundant calls.
Finally in your Fragment or Activity have something like this:
// TestFragment.java
public final class TestFragment extends Fragment implements OnDataCallback<ReportJobModel>, CustomRecyclerOnScrollListener {
#Bind(R.id.myRecyclerView)
RecyclerView myRecyclerView;
private JobsAdapter adapter;
private final JobReportHandler jobHandler = new JobReportHandler();
private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
private MyCustomEndlessScrollListener endlessScroll;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.my_list_fragment, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
endlessScroll = = new MyCustomEndlessScrollListener(this);
setUi();
initializeNetwork();
}
private void initializeNetwork() {
// after setting the UI Parameters
jobHandler.setDataCallback(this);
jobHandler.fetchJobsModel(compID, length);
}
#Override
public void onData(ReportJobModel dataModel) {
// just a safety mechanism to handle threading
// use the main thread dispatcher
mainThreadHandler.post(new Runnable() {
#Override
public void run() {
final ArrayList<JobItem> data = dataModel.getJobItems();
UiUtils.makeGone(loadingProgress);
if (myRecyclerView.getAdapter() == null || jobAdapter == null) {
jobAdapter = JobsAdapter(data);
myRecyclerView.setAdapter(jobAdapter);
myRecyclerView.setOnScrollChangeListener(endlessScroll);
} else {
jobAdapter.getItems().addAll(data);
jobAdapter.notifyItemRangeInserted(jobAdapter.getItems().size() -1, data.size());
}
}
});
}
#Override
public void onScrolledToBottom() {
jobHandler.updatePageNumber();
}
#Override
public void onError(final Throwable error) {
// just a safety mechanism to handle threading
// use the main thread dispatcher
mainThreadHandler.post(new Runnable() {
#Override
public void run() {
if (error.getMessage() != null && !error.getMessage().isEmpty()) {
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public void onDestroy() {
jobHandler.removeDataCallback();
super.onDestroy();
}
}
As you see the onScrolledToBottom() would be triggered through the CustomRecyclerScrollListener and this would then trigger the updatePageNumber() that would then call the fetchJobModel() and eventually you'll get a callback on your fragment.
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()
If I have an ArrayList<DialogFragment> containing DialogFragments of unknown size, how can I programmatically cue up each one so that once the first one is dismissed, the next one is shown, and so on?
for (int i = 0; i < tutorialViews.size(); i++) {
final int current = i;
DialogFragment someDialogFragment = dialogFragmentList.get(i);
if (i == 0) {
someDialogFragment .show(activity.get().getSupportFragmentManager(), "some_dialog_fragment");
}
if (i + 1 != dialogFragmentList.size() - 1) {
someDialogFragment.getDialog().setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface arg0) {
dialogFragmentList.get(current + 1).show(activity.get().getSupportFragmentManager(), "more_dialog_fragments");
}
});
}
}
Unforunately this doesn't work since the dialog object within a dialogFragment isn't instantiated yet, giving a nullPointerException for the getDialog() call
Create your own interface to callback when the fragmentdialog is closed.
OnDialogFragHide mListener;
public interface OnDialogFragHide {
public void onFragmentDismissed();
}
public void setOnFragDismissedListener(OnDialogFragHide listener) {
mListener = listener;
}
Register the interface in the for loop
if (i == 0) {
tutorial.show(activity.get().getSupportFragmentManager(), "smoking_hawt");
}
if (i != tutorialViews.size() - 1) {
tutorial.setOnFragDismissedListener(new OnDialogFragHide() {
#Override
public void onFragmentDismissed() {
tutorialViews.get(current + 1).show(activity.get().getSupportFragmentManager(), "some_tag");
}
});
}
Call upon the listener whenever the fragment is closed (i.e. in the FragmentDialog's onDismiss() and onCancel() methods, NOT the DIALOG's onDismiss / onCancel listeners.
#Override
public void onDismiss(DialogInterface dialog) {
if (mListener != null && !dismissed) {
dismissed = true;
mListener.onFragmentDismissed();
} else {
Log.e(TAG, "DialogFragmentDismissed not set");
}
super.onDismiss(dialog);
}
#Override
public void onCancel(DialogInterface dialog) {
if (mListener != null && dismissed) {
dismissed = true;
mListener.onFragmentDismissed();
} else {
Log.e(TAG, "DialogFragmentDismissed not set");
}
super.onCancel(dialog);
}
the dismissed boolean is for good measure to make the listener isn't called twice.