I'm working with fragments and flipview but I'm having some problems with this.
When my app opens the first screen show my feed with the FlipView. When I choose another tab of my fragments the fragment of the feed didn't hide or detach. I debugged many times and the code arrives in the detached line but didn't work.
Here is my code
MainActivity class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FontManager.getInstance().initialize(this, R.xml.fonts);
setContentView(R.layout.activity_main);
mFBSession = new FBSessionsManager();
mActionBar = getActionBar();
fm = getFragmentManager();
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
TabHost.OnTabChangeListener mTabChangeListener = new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged(String tabId) {
ft = fm.beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);
FeedPrincipalList mFeedFragment = (FeedPrincipalList) fm.findFragmentByTag(TAB_TAG_FEED);
EverythingFragmentList mEverythingFragment = (EverythingFragmentList) fm.findFragmentByTag(TAB_TAG_ALL_EVERYTHING);
PaymentFragment mPaymentFragment = (PaymentFragment) fm.findFragmentByTag(TAB_TAG_PAYMENT);
ConsultFragmentList mConsultFragmentList = (ConsultFragmentList) fm.findFragmentByTag(TAB_TAG_M_CONSULT);
ProfileFragmentList mProfileFragmentList = (ProfileFragmentList) fm.findFragmentByTag(TAB_TAG_M_PROFILE);
if (mFeedFragment != null){
ft.detach(mFeedFragment);
// ft.commit();
}
if (mEverythingFragment != null)
ft.detach(mEverythingFragment);
if (mPaymentFragment != null)
ft.detach(mPaymentFragment);
if (mConsultFragmentList != null)
ft.detach(mConsultFragmentList);
if (mProfileFragmentList != null){
ft.detach(mProfileFragmentList);
// ft.commit();
}
if (tabId.equalsIgnoreCase(TAB_TAG_FEED)) {
manageContextualActions(true, false);
if (mFeedFragment == null) {
mFeedFragment = new FeedPrincipalList();
ft.add(R.id.realTabContent, mFeedFragment, TAB_TAG_FEED);
} else {
mFeedFragment = new FeedPrincipalList();
ft.attach(mFeedFragment);
}
}
if (tabId.equalsIgnoreCase(TAB_TAG_ALL_EVERYTHING)) {
manageContextualActions(false, true);
if (mEverythingFragment == null) {
mEverythingFragment = new EverythingFragmentList();
ft.replace(R.id.realTabContent, mEverythingFragment, TAB_TAG_ALL_EVERYTHING);
} else {
ft.attach(mEverythingFragment);
}
}
if (tabId.equalsIgnoreCase(TAB_TAG_PAYMENT)) {
manageContextualActions(false, true);
if (mPaymentFragment == null) {
mPaymentFragment = new PaymentFragment();
ft.replace(R.id.realTabContent, mPaymentFragment, TAB_TAG_PAYMENT);
} else {
ft.attach(mPaymentFragment);
}
}
if (tabId.equalsIgnoreCase(TAB_TAG_M_CONSULT)) {
manageContextualActions(false, true);
if (mConsultFragmentList == null) {
mConsultFragmentList = new ConsultFragmentList();
ft.replace(R.id.realTabContent, mConsultFragmentList, TAB_TAG_M_CONSULT);
} else {
ft.attach(mConsultFragmentList);
}
}
if (tabId.equalsIgnoreCase(TAB_TAG_M_PROFILE)) {
manageContextualActions(false, false);
if (mProfileFragmentList == null) {
mProfileFragmentList = new ProfileFragmentList();
ft.replace(R.id.realTabContent, mProfileFragmentList, TAB_TAG_M_PROFILE);
} else {
mProfileFragmentList = new ProfileFragmentList();
ft.attach(mProfileFragmentList);
}
}
ft.commit();
}
};
mTabHost.setOnTabChangedListener(mTabChangeListener);
createAndConfigureTabs();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
}
public void setupActionBar(int stringTitleID) {
mActionBar.setDisplayShowCustomEnabled(true);
mActionBar.setDisplayShowTitleEnabled(false);
mActionBar.setDisplayUseLogoEnabled(false);
final LayoutInflater inflater = LayoutInflater.from(this);
final View customTitle = inflater.inflate(R.layout.custom_title, null);
((TextView) customTitle.findViewById(R.id.customTitleActionbar)).setText(getResources().getString(stringTitleID));
mActionBar.setCustomView(customTitle);
}
private void createAndConfigureTabs() {
mTabFeed = mTabHost.newTabSpec(TAB_TAG_FEED);
mTabFeed.setIndicator(null, getResources().getDrawable(R.drawable.custom_btn_feed));
mTabFeed.setContent(new TabContentCreator(this));
mTabHost.addTab(mTabFeed);
mTabAllEverything = mTabHost.newTabSpec(TAB_TAG_ALL_EVERYTHING);
mTabAllEverything.setIndicator(null, getResources().getDrawable(R.drawable.custom_btn_all_everything));
mTabAllEverything.setContent(new TabContentCreator(this));
mTabHost.addTab(mTabAllEverything);
mTabCameraAndPayment = mTabHost.newTabSpec(TAB_TAG_PAYMENT);
mTabCameraAndPayment.setIndicator(null, getResources().getDrawable(R.drawable.btn_camera));
mTabCameraAndPayment.setContent(new TabContentCreator(this));
mTabHost.addTab(mTabCameraAndPayment);
mTabConsult = mTabHost.newTabSpec(TAB_TAG_M_CONSULT);
mTabConsult.setIndicator(null, getResources().getDrawable(R.drawable.custom_btn_consult));
mTabConsult.setContent(new TabContentCreator(this));
mTabHost.addTab(mTabConsult);
mTabMyProfile = mTabHost.newTabSpec(TAB_TAG_M_PROFILE);
mTabMyProfile.setIndicator(null, getResources().getDrawable(R.drawable.custom_btn_profile));
mTabMyProfile.setContent(new TabContentCreator(this));
mTabHost.addTab(mTabMyProfile);
mTabWidget = mTabHost.getTabWidget();
for (int i = 0; i minor 5; i++) {
View v = mTabWidget.getChildAt(i);
v.setBackgroundResource(android.R.drawable.screen_background_light_transparent);
if (i == 4)
v.setPadding(0, 0, 0, 12);
}
}
private class TabContentCreator implements TabHost.TabContentFactory {
private Context mContext;
public TabContentCreator(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
return v;
}
}
FeedFragment class
public class FeedPrincipalList extends android.app.Fragment implements FlipView.OnFlipListener, FlipView.OnOverFlipListener, FlipView.OnClickListener {
private static int timelinePage = 1, mPageCount = 0;
private FlipView mFlipView;
private FeedPrincipalAdapter mAdapter;
private FBSessionsManager fbSessionsManager;
private List mList;
private Context context;
private int posicaoTela;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
context = getActivity().getApplicationContext();
View view = inflater.inflate(R.layout.feed_flipview, container);
((MainFragmentActivity) getActivity()).setupActionBar(R.string.title_fragment_feed);
mFlipView = (FlipView) view.findViewById(R.id.fv_feedFlipView_FlipView);
mFlipView.setOnFlipListener(this);
mFlipView.setOverFlipMode(OverFlipMode.RUBBER_BAND);
mFlipView.setEmptyView(view.findViewById(R.id.empty_view));
mFlipView.setOnOverFlipListener(this);
mFlipView.setOnClickListener(this);
fbSessionsManager = new FBSessionsManager(getActivity());
if (mList == null)
new LoadFeedPrincipalData().execute();
return super.onCreateView(inflater,container,savedInstanceState);
}
#Override
public void onFlippedToPage(FlipView v, int position, long id) {
Log.i("pageflip", "Page: " + position);
posicaoTela = position;
if(position > mFlipView.getPageCount()-3 && mFlipView.getPageCount() {
private UtilWS ws;
private JSONObject toSend;
private JsonArray rsArray;
private JsonParser parser;
public LoadFeedPrincipalData() {
ws = new UtilWS();
toSend = new JSONObject();
parser = new JsonParser();
}
#Override
protected Void doInBackground(Void... params) {
try {
toSend.put("token", fbSessionsManager.getStoredPrivateSession()[0]);
toSend.put("userId", fbSessionsManager.getStoredPrivateSession()[1]);
toSend.put("page", timelinePage);
String[] jsonResult = ws.post(UtilWS.URL_TIMELINE, toSend.toString());
if (jsonResult[0].equals("200")) {
JsonObject temp = parser.parse(jsonResult[1]).getAsJsonObject();
Log.i("JSON",": "+temp.toString());
if (temp.get("success").getAsBoolean()) {
rsArray = temp.get("looks").getAsJsonArray();
if (mPageCount == 0)
mPageCount = temp.get("pageCount").getAsInt();
for (JsonElement el : rsArray) {
if (mList == null)
mList = new ArrayList();
temp = (JsonObject) el;
FeedPrincipalTO tempTudo = new FeedPrincipalTO(temp.get("lookId").getAsString(), temp.get("photoUrl1").getAsString(), temp.get("photoUrl2").getAsString(), temp.get("jaVotou").getAsBoolean(),temp.get("photoVoted").getAsInt() ,temp.get("photo1Total").getAsString(), temp.get("photo2Total").getAsString());
mList.add(tempTudo);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
if (mList != null) {
Log.i("mList","mLista");
mAdapter = new FeedPrincipalAdapter(context,mList);
mAdapter.setCallback(new FeedPrincipalAdapter.Callback() {
#Override
public void onPageRequested(int page) {
mFlipView.smoothFlipTo(page);
}
#Override
public void voteUp(int position) {
Log.i("TESTE","position = " + posicaoTela);
mAdapter.getView(position, null, null).postInvalidate();
// mAdapter.notifyDataSetChanged();
}
});
if (timelinePage == 1) {
mFlipView.setAdapter(mAdapter);
// initListenerList();
} else {
((FeedPrincipalAdapter) mFlipView.getAdapter()).updateList(mList);
((FeedPrincipalAdapter) mFlipView.getAdapter()).notifyDataSetChanged();
}
} else {
mFlipView.setAdapter(new FeedPrincipalAdapter(context,null));
}
}
// private void initListenerList() {
// getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
// #Override
// public void onScrollStateChanged(AbsListView view, int scrollState) {
//
// }
//
// #Override
// public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount != 0) {
// if (timelinePage minor mPageCount) {
// timelinePage++;
// new LoadFeedPrincipalData().execute();
// }
// }
// }
// });
// }
}
}
Please, help me with this!!!
I'm using the FlipView https://github.com/emilsjolander/android-FlipView
Thanks!!!
Finally I solved this problem.
First I changed my Main Class a little.
I changed this two ifs (this fragments uses FlipView) in the MainActivity class.
if (tabId.equalsIgnoreCase(TAB_TAG_FEED)) {
manageContextualActions(true, false);
if (mFeedFragment == null) {
mFeedFragment = new FeedPrincipalList();
ft.add(R.id.realTabContent, mFeedFragment, TAB_TAG_FEED);
} else {
// mFeedFragment = new FeedPrincipalList();
ft.attach(mFeedFragment);
}
}
if (tabId.equalsIgnoreCase(TAB_TAG_M_PROFILE)) {
manageContextualActions(false, false);
if (mProfileFragmentList == null) {
mProfileFragmentList = new ProfileFragmentList();
ft.add(R.id.realTabContent, mProfileFragmentList, TAB_TAG_M_PROFILE);
} else {
// mProfileFragmentList = new ProfileFragmentList();
ft.attach(mProfileFragmentList);
}
}
Second I changed my method onCreateView of my FeedFragment class.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
context = getActivity().getApplicationContext();
((MainFragmentActivity) getActivity()).setupActionBar(R.string.title_fragment_feed);
fbSessionsManager = new FBSessionsManager(getActivity());
if (mList == null){
view = inflater.inflate(R.layout.feed_flipview, container,true);
mFlipView = (FlipView) view.findViewById(R.id.fv_feedFlipView_FlipView);
mFlipView.setOnFlipListener(this);
mFlipView.setOverFlipMode(OverFlipMode.RUBBER_BAND);
mFlipView.setEmptyView(view.findViewById(R.id.empty_view));
mFlipView.setOnOverFlipListener(this);
new LoadFeedPrincipalData().execute();
}
return super.onCreateView(inflater,container,savedInstanceState);
}
You can see the difference. I only inflate the view in the first time. After this my mList(it's a List of MyGetSetClass) it's not null anymore.
And to finish I Override this two methods on my FeedFragment class.
#Override
public void onDetach() {
super.onDetach();
// Log.i("onDetach", "FeedPrincipalList");
mList = null;
timelinePage = 1;
mPageCount = 0;
}
#Override
public void onStart() {
super.onStart();
// Log.i("onStart", "FeedPrincipalList");
this.mFlipView.setVisibility(View.VISIBLE);
}
#Override
public void onStop() {
super.onStop();
// Log.i("onStop","FeedPrincipalList");
this.mFlipView.setVisibility(View.INVISIBLE);
}
In the detach method I clean all my static variables that I will use when I start the app again.
The onStart and the onStop I use to change the Visibility of my FlipView.
That's it.
I hope this help everyone!!!
Related
I am a beginner in the world of programming, and now I am working on developing an audio player by adding an equalizer, but I encountered a problem, which is after 10 seconds of pressing the back button and exiting the fragment, the equalizer stops and does not work until after opening the page again.
Also, when playing another audio, the equalizer stops and does not work until the fragment is opened again.
I have tried to fix it but to no avail, Plz Help..
public class MainActivityEqualizer extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_equalizer);
loadEqualizerSettings();
final int sessionId = MyConstants.exoPlayer.getAudioSessionId();
EqualizerFragment equalizerFragment = EqualizerFragment.newBuilder()
.setAccentColor(Color.parseColor("#4caf50"))
.setAudioSessionId(sessionId)
.build();
getSupportFragmentManager().beginTransaction()
.replace(R.id.eqFrame, equalizerFragment)
.commit();
}
public void newBuild()
{
final int sessionId = MyConstants.exoPlayer.getAudioSessionId();
EqualizerFragment equalizerFragment = EqualizerFragment.newBuilder()
.setAccentColor(Color.parseColor("#4caf50"))
.setAudioSessionId(sessionId)
.build();
getSupportFragmentManager().beginTransaction()
.replace(R.id.eqFrame, equalizerFragment)
.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.itemEqDialog) {
showInDialog();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onStop() {
super.onStop();
saveEqualizerSettings();
}
#Override
protected void onPause() {
try {
newBuild();
//mediaPlayer.pause();
} catch (Exception ex) {
Toast.makeText(MainActivityEqualizer.this,ex+"",Toast.LENGTH_LONG).show();
//ignore
}
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
newBuild();
try {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//loadEqualizerSettings();
//mediaPlayer.start();
}
}, 200);
} catch (Exception ex) {
//ignore
}
}
private void showInDialog() {
int sessionId = MyConstants.exoPlayer.getAudioSessionId();
if (sessionId > 0) {
DialogEqualizerFragment fragment = DialogEqualizerFragment.newBuilder()
.setAudioSessionId(sessionId)
.title(R.string.app_name)
.themeColor(ContextCompat.getColor(this, R.color.primaryColor))
.textColor(ContextCompat.getColor(this, R.color.textColor))
.accentAlpha(ContextCompat.getColor(this, R.color.playingCardColor))
.darkColor(ContextCompat.getColor(this, R.color.primaryDarkColor))
.setAccentColor(ContextCompat.getColor(this, R.color.secondaryColor))
.build();
fragment.show(getSupportFragmentManager(), "eq");
}
}
private void saveEqualizerSettings(){
if (Settings.equalizerModel != null){
EqualizerSettings settings = new EqualizerSettings();
settings.bassStrength = Settings.equalizerModel.getBassStrength();
settings.presetPos = Settings.equalizerModel.getPresetPos();
settings.reverbPreset = Settings.equalizerModel.getReverbPreset();
settings.seekbarpos = Settings.equalizerModel.getSeekbarpos();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Gson gson = new Gson();
preferences.edit()
.putString(PREF_KEY, gson.toJson(settings))
.apply();
}
}
private void loadEqualizerSettings(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Gson gson = new Gson();
EqualizerSettings settings = gson.fromJson(preferences.getString(PREF_KEY, "{}"), EqualizerSettings.class);
EqualizerModel model = new EqualizerModel();
model.setBassStrength(settings.bassStrength);
model.setPresetPos(settings.presetPos);
model.setReverbPreset(settings.reverbPreset);
model.setSeekbarpos(settings.seekbarpos);
Settings.isEqualizerEnabled = true;
Settings.isEqualizerReloaded = true;
Settings.bassStrength = settings.bassStrength;
Settings.presetPos = settings.presetPos;
Settings.reverbPreset = settings.reverbPreset;
Settings.seekbarpos = settings.seekbarpos;
Settings.equalizerModel = model;
}
public static final String PREF_KEY = "equalizer";
public static void newLoadEqualizerSettings(){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MyConstants.context);
Gson gson = new Gson();
EqualizerSettings settings = gson.fromJson(preferences.getString(PREF_KEY, "{}"), EqualizerSettings.class);
EqualizerModel model = new EqualizerModel();
model.setBassStrength(settings.bassStrength);
model.setPresetPos(settings.presetPos);
model.setReverbPreset(settings.reverbPreset);
model.setSeekbarpos(settings.seekbarpos);
Settings.isEqualizerEnabled = true;
Settings.isEqualizerReloaded = true;
Settings.bassStrength = settings.bassStrength;
Settings.presetPos = settings.presetPos;
Settings.reverbPreset = settings.reverbPreset;
Settings.seekbarpos = settings.seekbarpos;
Settings.equalizerModel = model;
}
}
and here is onCreate method of EqualizerFragment
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Settings.isEditing = true;
if (getArguments() != null && getArguments().containsKey(ARG_AUDIO_SESSIOIN_ID)) {
audioSesionId = getArguments().getInt(ARG_AUDIO_SESSIOIN_ID);
}
if (Settings.equalizerModel == null) {
Settings.equalizerModel = new EqualizerModel();
Settings.equalizerModel.setReverbPreset(PresetReverb.PRESET_NONE);
Settings.equalizerModel.setBassStrength((short) (1000 / 19));
}
mEqualizer = new Equalizer(0, audioSesionId);
bassBoost = new BassBoost(0, audioSesionId);
bassBoost.setEnabled(Settings.isEqualizerEnabled);
BassBoost.Settings bassBoostSettingTemp = bassBoost.getProperties();
BassBoost.Settings bassBoostSetting = new BassBoost.Settings(bassBoostSettingTemp.toString());
bassBoostSetting.strength = Settings.equalizerModel.getBassStrength();
bassBoost.setProperties(bassBoostSetting);
presetReverb = new PresetReverb(0, audioSesionId);
presetReverb.setPreset(Settings.equalizerModel.getReverbPreset());
presetReverb.setEnabled(Settings.isEqualizerEnabled);
mEqualizer.setEnabled(Settings.isEqualizerEnabled);
if (Settings.presetPos == 0) {
for (short bandIdx = 0; bandIdx < mEqualizer.getNumberOfBands(); bandIdx++) {
mEqualizer.setBandLevel(bandIdx, (short) Settings.seekbarpos[bandIdx]);
}
} else {
mEqualizer.usePreset((short) Settings.presetPos);
}
}
So I've been trying to fix this issue for so many hours but can't find the cause behind it.
Issue: My app shows data from my API into recyclerView, a standard feature. The issue comes when I use the search function. When I search for something, my search adapter shows the query data but going back to my Main fragment again, the view loader shows content fine but when I click on it, search items are actually being loaded instead.
Check my app to find out what I'm talking about: https://play.google.com/store/apps/details?id=envision.apps.newsextra
To reproduce, search for something, click on any article from search results, then go back and click any article from main feed, search items are actually being loaded instead.
Here's my main fragment:
public class FeedsFragment extends Fragment implements ArticleListener, LocalMessageCallback {
private PullRefreshLayout pullRefreshLayout;
private RecyclerView recyclerView;
private FeedsAdapter adapter;
private View layout;
private ArrayList<Object> data = new ArrayList<>();
private List<Favorites> favorites = new ArrayList<>();
private List<Articles> articles = new ArrayList<>();
private boolean init = true;
private DataViewModel dataViewModel;
private NativeAdsManager mNativeAdsManager;
private String sort_date = SharedPrefernces.getFeedSortDate();
public static FeedsFragment newInstance() {
return new FeedsFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
layout = inflater.inflate(R.layout.feeds_fragment_layout, container, false);
init_views();
setRecyclerView();
initNativeAds();
dataViewModel = ViewModelProviders.of(this).get(DataViewModel.class);
dataViewModel.getFavorites().observe(this, favorites -> {
if(favorites!=null){
this.favorites = favorites;
}
});
dataViewModel.getArticles().observe(this, articles -> {
this.articles = articles;
if(init) {
if (articles!= null && articles.size() > 0) {
//this.articles = articles;
data = new ArrayList<>();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(getString(R.string.all_stories))){
data.add(new Info("Showing stories based on all your interests"));
}else{
data.add(new Info("Showing stories on "+SharedPrefernces.getActiveInterest()));
}
data.addAll(articles);
adapter.setData(data);
}
init = false;
}
});
new Handler().postDelayed(() -> {
//we first check if time set to fetch feeds again has elapsed
pullRefreshLayout.setRefreshing(true);
fetchFeeds();
SharedPrefernces.setReloadArticles(false);
}, 1000);
return layout;
}
//init view layouts
private void init_views(){
pullRefreshLayout = layout.findViewById(R.id.pullRefreshLayout);
int[] colorScheme = getResources().getIntArray(R.array.refresh_color_scheme);
pullRefreshLayout.setColorSchemeColors(colorScheme);
pullRefreshLayout.setOnRefreshListener(this::fetchFeeds);
}
//init recyclerview
private void setRecyclerView() {
recyclerView = (RecyclerView) layout.findViewById(R.id.recyclerView);
GridLayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 1);
recyclerView.setLayoutManager(mLayoutManager);
adapter = new FeedsAdapter(getActivity(),recyclerView,this);
//int index = movies.size() - 1;
adapter.setLoadMoreListener(() -> recyclerView.post(() -> {
if(data.size()>0 && data.get(1) instanceof Articles){
adapter.setLoader();
loadMoreFeeds();
}
}));
recyclerView.setAdapter(adapter);
}
private void initNativeAds(){
mNativeAdsManager = new NativeAdsManager(getActivity(), getResources().getString(R.string.FACEBOOK_FEED_NATIVE_AD), 10);
mNativeAdsManager.loadAds();
mNativeAdsManager.setListener(new NativeAdsManager.Listener() {
#Override
public void onAdsLoaded() {
}
#Override
public void onAdError(AdError adError) {
}
});
}
private void fetchFeeds(){
if(!NetworkUtil.hasConnection(getActivity())) {
setNetworkError();
return;
}
NetworkService service = StringApiClient.createServiceWithToken(NetworkService.class);
try {
JSONObject jsonData = new JSONObject();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(getString(R.string.all_stories))) {
jsonData.put("interests", new JSONArray(SharedPrefernces.getUserInterests()));
}else{
ArrayList<String> interest = new ArrayList<>();
interest.add(SharedPrefernces.getActiveInterest());
jsonData.put("interests", new JSONArray(interest));
}
if(SharedPrefernces.getUserUnfollowedFeedSources()!=null && SharedPrefernces.getUserUnfollowedFeedSources().size()>0) {
jsonData.put("sources", new JSONArray(SharedPrefernces.getUserUnfollowedFeedSources()));
}
jsonData.put("location", Misc.getCurrentCountryCode());
String requestBody = jsonData.toString();
Log.e("final requestbody",requestBody);
Call<String> callAsync = service.getArticles(requestBody);
callAsync.enqueue(new Callback<String>() {
#Override
public void onResponse(#NonNull Call<String> call, #NonNull Response<String> response) {
Log.e("response",String.valueOf(response.body()));
pullRefreshLayout.setRefreshing(false);
if(response.body()==null){
setNetworkError();
return;
}
try {
JSONObject res = new JSONObject(response.body());
// Add Your Logic
if(res.getString("status").equalsIgnoreCase("ok")){
//create a new object
data = new ArrayList<>();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(getString(R.string.all_stories))){
data.add(new Info("Showing stories based on all your interests"));
}else{
data.add(new Info("Showing Stories on "+SharedPrefernces.getActiveInterest()));
}
sort_date = res.getString("date");
SharedPrefernces.setFeedSortDate(sort_date);
ArrayList<Articles> articles = JsonParser.getArticles(res.getJSONArray("feeds"));
//delete all previously store articles, and add new items to database
dataViewModel.deleteAllArticles();
dataViewModel.insertAllArticles(articles);
//append interests to our object list
data.addAll(articles);
//set data to adapter
adapter.setData(data);
//set last fetched time to sharedpreferences
if(articles.size()>0)SharedPrefernces.setArticleLastRefreshTime(System.currentTimeMillis());
}
}catch (Exception e){
e.printStackTrace();
Log.e("error",e.getMessage());
}
}
#Override
public void onFailure(#NonNull Call<String> call, #NonNull Throwable throwable) {
Log.e("error",String.valueOf(throwable.getMessage()));
setNetworkError();
pullRefreshLayout.setRefreshing(false);
}
});
} catch (JSONException e) {
Log.e("parse error",e.getMessage());
e.printStackTrace();
}
}
private void loadMoreFeeds(){
// ToDo
}
private void setNetworkError(){
dataViewModel.deleteAllArticles();
dataViewModel.insertAllArticles(articles);
pullRefreshLayout.setRefreshing(false);
data = new ArrayList<>();
if(SharedPrefernces.getActiveInterest().equalsIgnoreCase(App.getContext().getString(R.string.all_stories))){
data.add(new Info("Showing stories based on all your interests"));
}else{
data.add(new Info("Showing stories on "+SharedPrefernces.getActiveInterest()));
}
data.add(new Error(""));
adapter.setData(data);
}
#Override
public void OnItemClick(Articles article) {
//List<Integer> contestWinners = data.subList(0, 5);
int position = 0;
for (Articles arts: this.articles) {
if(arts.getId() == article.getId()){
position = this.articles.indexOf(arts);
}
}
Gson gson = new Gson();
String json = gson.toJson(article);
Intent intent = new Intent(getActivity(), FeedViewerActivity.class);
intent.putExtra("position", position);
intent.putExtra("article",json);
intent.putExtra(FeedViewerActivity.VIEW_TYPE, Constants.ARTICLE_VIEW);
intent.putExtra(FeedViewerActivity.VIEW_SIZE, get_feeds_view_size(this.articles,position));
startActivity(intent);
Objects.requireNonNull(getActivity()).overridePendingTransition(R.anim.slide_left_in, R.anim.still);
}
#Override
public void OnPinClick(Articles articles,String action) {
if(articles==null)return;
if(action.equalsIgnoreCase(getResources().getString(R.string.add_pin))){
dataViewModel.insertFavorites(ObjectMapper.mapFavorites(articles));
}else {
dataViewModel.deleteFavorite(ObjectMapper.mapFavorites(articles).getId());
}
}
#Override
public void OnShareClick(Articles articles) {
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_SUBJECT, articles.getTitle());
share.putExtra(Intent.EXTRA_TEXT, articles.getLink());
startActivity(Intent.createChooser(share, "Share Article"));
}
#Override
public boolean IsPinned(Articles articles) {
for (Favorites fav: favorites) {
if(fav.getId() == articles.getId()){
return true;
}
}
return false;
}
#Override
public void requestAds(int position) {
NativeAd ad = mNativeAdsManager.nextNativeAd();
if(ad!=null){
adapter.setAd(ad,position);
}
}
#Override
public void loadSingleFeedsActivity(Articles articles) {
Gson gson = new Gson();
String myJson = gson.toJson(articles);
Intent intent = new Intent(getActivity(), FeedSourceActivity.class);
intent.putExtra("article", myJson);
startActivity(intent);
}
#Override
public boolean isSingleFeedsActivity() {
return false;
}
#Override
public void onDestroy() {
LocalMessageManager.getInstance().send(R.id.remove_listener);
LocalMessageManager.getInstance().removeListener(this);
super.onDestroy();
}
#Override
public void onStart() {
super.onStart();
LocalMessageManager.getInstance().addListener(this);
}
#Override
public void handleMessage(#NonNull LocalMessage localMessage) {
if(localMessage.getId() == R.id.reload_feeds){
pullRefreshLayout.setRefreshing(true);
fetchFeeds();
SharedPrefernces.setReloadArticles(false);
}
if(localMessage.getId() == R.id.scroll_feeds_to_top){
recyclerView.smoothScrollToPosition(0);
}
}
}
Adapter:
public class FeedsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener {
private ArrayList<Object> data = new ArrayList<>();
private Context context;
private int lastItemPosition = -1;
private final int VIEW_TYPE_HEADER = 1;
private final int VIEW_TYPE_LIST = 2;
private final int VIEW_TYPE_LOADER = 3;
private final int VIEW_TYPE_NETWORK_ERROR = 4;
private final int VIEW_TYPE_INFO = 5;
private final int VIEW_TYPE_AD = 6;
private boolean isLoading = false;
private LoadMoreListener loadMoreListener;
private int visibleThreshold = 2;//visible items before loading next feeds
private int firstVisibleItem,lastVisibleItem, totalItemCount;
private ArticleListener articleListener;
public FeedsAdapter(Context context, RecyclerView mRecyclerView, ArticleListener articleListener) {
this.context=context;
this.articleListener = articleListener;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LocalMessageManager.getInstance().send(R.id.recyclerview_scroll);
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if ((firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD) % Constants.ADS.LOAD_ADS_AT_POSITION == 0){
//
int pos = firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD;
if(pos > lastItemPosition && data.size()>pos && data.get(pos - 1) != null/*dont load ad if we r currently making a request*/) {
if (!(data.get(pos) instanceof NativeAd)) {
articleListener.requestAds(pos);
}
}
}
if (!isLoading && NetworkUtil.hasConnection(context)) {
if (totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (loadMoreListener != null) {
loadMoreListener.onLoadMore();
}
isLoading = true;
}
}
}
});
}
#Override
public int getItemViewType(int position) {
if(data.get(position) instanceof Error)return VIEW_TYPE_NETWORK_ERROR;
if(data.get(position) instanceof Info)return VIEW_TYPE_INFO;
if(data.get(position) instanceof NativeAd)return VIEW_TYPE_AD;
if(SharedPrefernces.get_feed_images_show()
&& SharedPrefernces.get_feed_type() == 1
&& position==1 && data.get(position) instanceof Articles){
return VIEW_TYPE_HEADER;
}
if(data.get(position) == null)return VIEW_TYPE_LOADER;
return VIEW_TYPE_LIST;
}
public void setData(ArrayList<Object> objectList) {
Log.e("objectList size",String.valueOf(objectList.size()));
this.data.clear();
this.data.addAll(objectList);
Log.e("data size",String.valueOf(data.size()));
this.notifyDataSetChanged();
}
public void setMoreData(ArrayList<Articles> articles) {
//int start = data.size() + 2;
data.addAll(articles);
//this.notifyItemRangeInserted(start, articles.size());
this.notifyDataSetChanged();
}
public void setAd(NativeAd ad, int pos) {
data.add(pos, ad);
this.notifyItemInserted(pos);
}
#Override
public int getItemCount() {
return data != null ? data.size() : 0;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, final int position) {
lastItemPosition = position;
//Log.e("view type",String.valueOf(holder.getItemViewType()));
switch (holder.getItemViewType()) {
case VIEW_TYPE_LIST: case VIEW_TYPE_HEADER:
final ArticleViewHolder viewHolder = (ArticleViewHolder) holder;
viewHolder.bindTo((Articles) data.get(position));
break;
case VIEW_TYPE_LOADER:
final ViewLoader viewLoader = (ViewLoader) holder;
viewLoader.rotateLoading.start();
break;
case VIEW_TYPE_NETWORK_ERROR:
ViewError viewError = (ViewError) holder;
if(SharedPrefernces.getUseNightMode()){
viewError.img.setColorFilter(App.getContext().getResources().getColor(R.color.white));
}else{
viewError.img.setColorFilter(App.getContext().getResources().getColor(R.color.black));
}
break;
case VIEW_TYPE_INFO:
final ViewInfo viewInfo = (ViewInfo) holder;
Info info = (Info)data.get(position);
viewInfo.body.setText(info.getContent());
break;
case VIEW_TYPE_AD:
final AdsViewHolder adsViewHolder = (AdsViewHolder) holder;
NativeAd nativeAd = (NativeAd)data.get(position);
adsViewHolder.bind(nativeAd);
break;
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int i) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(context);
switch (i) {
case VIEW_TYPE_HEADER:
View v = inflater.inflate(R.layout.feeds_header, parent, false);
viewHolder = new ArticleViewHolder(v, articleListener);
break;
case VIEW_TYPE_LIST:
View va;
if(SharedPrefernces.get_feed_images_show() && SharedPrefernces.get_feed_type()==0){
va = inflater.inflate(R.layout.large_image_feeds_list, parent, false);
}else{
va = inflater.inflate(R.layout.feeds_list, parent, false);
}
viewHolder = new ArticleViewHolder(va, articleListener);
break;
case VIEW_TYPE_LOADER:
View ld = inflater.inflate(R.layout.loader, parent, false);
viewHolder = new ViewLoader(ld);
break;
case VIEW_TYPE_NETWORK_ERROR:
View ne = inflater.inflate(R.layout.no_stories, parent, false);
viewHolder = new ViewError(ne);
break;
case VIEW_TYPE_INFO:
View info = inflater.inflate(R.layout.info, parent, false);
viewHolder = new ViewInfo(info);
break;
case VIEW_TYPE_AD:
View ads = inflater.inflate(R.layout.ad_item_large, parent, false);
viewHolder = new AdsViewHolder(ads);
break;
}
return viewHolder;
}
#Override
public void onClick(View view) {
//int pos = (int) view.getTag();
switch (view.getId()){
case R.id.pin:
break;
case R.id.share:
break;
}
}
public class ViewLoader extends RecyclerView.ViewHolder {
private RotateLoading rotateLoading;
ViewLoader(View view) {
super(view);
rotateLoading = (RotateLoading) view.findViewById(R.id.rotateloading);
}
}
public class ViewError extends RecyclerView.ViewHolder {
private ImageView img;
ViewError(View view) {
super(view);
img = view.findViewById(R.id.img);
}
}
public class ViewInfo extends RecyclerView.ViewHolder {
private TextView body;
ViewInfo(View view) {
super(view);
body = view.findViewById(R.id.body);
}
}
public void setLoaded(){
data.remove(data.size()-1);
this.notifyItemRemoved(data.size()-1);
isLoading = false;
}
public void setLoadMoreListener(LoadMoreListener loadMoreListener) {
this.loadMoreListener = loadMoreListener;
}
public void setLoader(){
data.add(null);
this.notifyItemInserted(data.size()-1);
}
}
Search Adapter:
public class SearchAdapter extends RecyclerView.Adapter< RecyclerView.ViewHolder>{
private List<Object> items = new ArrayList<>();
private final int VIEW_TYPE_MEDIA = 0;
private final int VIEW_TYPE_LOADING = 1;
private final int VIEW_TYPE_AD = 2;
private SearchClickListener searchClickListener;
private LoadMoreListener mOnLoadMoreListener;
private boolean isLoading;
private int visibleThreshold = 2;
public int firstVisibleItem,lastVisibleItem, totalItemCount;
private int lastItemPosition = -1;
public SearchAdapter(RecyclerView mRecyclerView, SearchClickListener searchClickListener) {
this.searchClickListener = searchClickListener;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();
totalItemCount = linearLayoutManager.getItemCount();
lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if ((firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD) % Constants.ADS.LOAD_ADS_AT_POSITION == 0){
//
int pos = firstVisibleItem + Constants.ADS.NUMBER_OF_ITEMS_BEFORE_REQUEST_AD;
if(pos > lastItemPosition && items.size()>pos && items.get(pos - 1) != null/*dont load ad if we r currently making a request*/) {
if (!(items.get(pos) instanceof NativeAd)) {
searchClickListener.requestAds(pos);
}
}
}
if (!isLoading && NetworkUtil.hasConnection(App.getContext())) {
if (totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (items.size() > 1 && mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
}
});
}
public void setMoreAdapter(List<Search> data) {
items.addAll(data);
//items.addAll((items.size()-1),data);
this.notifyDataSetChanged();
}
public void setAdapter(List<Search> data) {
items = new ArrayList<>();
items.addAll(data);
this.notifyDataSetChanged();
}
#Override
public int getItemCount() {
return items != null ? items.size() : 0;
}
#Override
public int getItemViewType(int position) {
if(items.get(position) instanceof NativeAd)return VIEW_TYPE_AD;
if(items.get(position)==null && position == (items.size()-1)){
return VIEW_TYPE_LOADING;
}else{
return VIEW_TYPE_MEDIA;
}
}
public void setLoader() {
items.add(null);
this.notifyItemInserted(items.size() - 1);
}
public void setAd(NativeAd ad, int pos) {
items.add(pos, ad);
this.notifyItemInserted(pos);
}
public void removeLoader() {
items.remove(items.size() - 1);
this.notifyItemRemoved(items.size());
}
public void setOnLoadMoreListener(LoadMoreListener mOnLoadMoreListener) {
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (i) {
case VIEW_TYPE_MEDIA:
View v = inflater.inflate(R.layout.search_list, viewGroup, false);
viewHolder = new SearchViewHolder(v,searchClickListener);
viewHolder.itemView.setClickable(true);
break;
case VIEW_TYPE_LOADING:
View vL = inflater.inflate(R.layout.loader, viewGroup, false);
viewHolder = new LoadingViewHolder(vL);
break;
case VIEW_TYPE_AD:
View ads = inflater.inflate(R.layout.ad_item_small, viewGroup, false);
viewHolder = new AdsViewHolder(ads);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
lastItemPosition = i;
switch (holder.getItemViewType()) {
case VIEW_TYPE_LOADING:
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.start();
break;
case VIEW_TYPE_MEDIA:
final SearchViewHolder viewHolder = (SearchViewHolder) holder;
final Search ci = (Search)items.get(i);
viewHolder.bindTo(ci);
break;
case VIEW_TYPE_AD:
final AdsViewHolder adsViewHolder = (AdsViewHolder) holder;
NativeAd nativeAd = (NativeAd)items.get(i);
adsViewHolder.bind(nativeAd);
break;
}
}
private static class LoadingViewHolder extends RecyclerView.ViewHolder {
private RotateLoading progressBar;
private LoadingViewHolder(View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.rotateloading);
}
}
public void setLoaded() {
isLoading = false;
}
public interface SearchClickListener {
void onClick(Search search);
void requestAds(int position);
}
}
Seriously any help will be greatly appreciated.
Due to the character limit, I'm posting my viewHolder code here as a comment.
ArticleViewHolder:
public class ArticleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, LocalMessageCallback {
private Articles articles;
private TextView title,interest,time,source,content;
private LinearLayout revealView;
private ImageView thumbnail,pin,source_link;
private Animation alphaAnimation;
private float pixelDensity;
private boolean flag = false;
private RelativeLayout revealLayout,layoutButtons;
private ArticleListener articleListener;
private CardView cardView;
private String pin_action = "add";
public ArticleViewHolder(View view, ArticleListener articleListener) {
super(view);
this.articleListener = articleListener;
pixelDensity = App.getContext().getResources().getDisplayMetrics().density;
alphaAnimation = AnimationUtils.loadAnimation(App.getContext(), R.anim.alpha_anim);
LocalMessageManager.getInstance().addListener(this);
FrameLayout source_holder = view.findViewById(R.id.source_holder);
cardView = view.findViewById(R.id.card_view);
source_link = view.findViewById(R.id.source_link);
revealLayout = view.findViewById(R.id.revealLayout);
revealView = view.findViewById(R.id.revealView);
layoutButtons = view.findViewById(R.id.layoutButtons);
title = view.findViewById(R.id.title);
content = view.findViewById(R.id.content);
interest = view.findViewById(R.id.interest);
thumbnail = view.findViewById(R.id.thumbnail);
time = view.findViewById(R.id.time);
source = view.findViewById(R.id.source);
ImageView reveal = view.findViewById(R.id.reveal);
ImageView close = view.findViewById(R.id.close);
pin = view.findViewById(R.id.pin);
ImageView share = view.findViewById(R.id.share);
reveal.setOnClickListener(this);
close.setOnClickListener(this);
pin.setOnClickListener(this);
share.setOnClickListener(this);
title.setOnClickListener(this);
content.setOnClickListener(this);
thumbnail.setOnClickListener(this);
source_holder.setOnClickListener(this);
}
public void bindTo(Articles articles) {
this.articles = articles;
title.setText(articles.getTitle());
content.setText(articles.getContent().replace("\n", " ").replace("\r", " "));
interest.setText(articles.getInterest());
//Log.e("thumbnail",String.valueOf(articles.getThumbnail()));
if(SharedPrefernces.get_feed_images_show()) {
thumbnail.setVisibility(View.VISIBLE);
ImageLoader.loadImage(thumbnail, articles.getThumbnail());
}else{
thumbnail.setVisibility(View.GONE);
}
time.setText(TimUtil.timeAgo(articles.getTimeStamp()));
String _source = articles.getSource();
source.setText(_source.substring(0,1).toUpperCase() + _source.substring(1).toLowerCase());
if(articleListener.IsPinned(articles)){
set_pin_view(true);
pin_action = App.getContext().getResources().getString(R.string.remove_pin);
}else{
set_pin_view(false);
pin_action = App.getContext().getResources().getString(R.string.add_pin);
}
if(flag){
revealView.setVisibility(View.VISIBLE);
layoutButtons.setVisibility(View.VISIBLE);
}else{
revealView.setVisibility(View.GONE);
layoutButtons.setVisibility(View.GONE);
}
if(articleListener.isSingleFeedsActivity()){
source_link.setVisibility(View.GONE);
}else{
source_link.setVisibility(View.VISIBLE);
}
if(!SharedPrefernces.getUseNightMode()){
cardView.setCardBackgroundColor(App.getContext().getResources().getColor(R.color.material_grey_100));
}
}
private void set_pin_view(boolean isPinned){
Drawable mDrawable;
if(!isPinned){
mDrawable = ContextCompat.getDrawable(App.getContext(),R.drawable.pin_outline);
mDrawable.setColorFilter(new
PorterDuffColorFilter(App.getContext().getResources().getColor(R.color.material_grey_200), PorterDuff.Mode.SRC_IN));
}else{
mDrawable = ContextCompat.getDrawable(App.getContext(),R.drawable.pin_outline);
mDrawable.setColorFilter(new
PorterDuffColorFilter(App.getContext().getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_IN));
}
pin.setImageDrawable(mDrawable);
}
#Override
public void onClick(View view) {
LocalMessageManager.getInstance().send(R.id.hide_reveal_layout,articles.getId());
if (articleListener != null) {
if(view.getId() == R.id.reveal || view.getId() == R.id.close){
revealLayout();
}else if(view.getId() == R.id.source_holder){
articleListener.loadSingleFeedsActivity(articles);
}else if(view.getId() == R.id.pin){
articleListener.OnPinClick(articles,pin_action);
if(pin_action.equalsIgnoreCase(App.getContext().getResources().getString(R.string.add_pin))){
pin_action = App.getContext().getResources().getString(R.string.remove_pin);
set_pin_view(true);
}else{
pin_action = App.getContext().getResources().getString(R.string.add_pin);
set_pin_view(false);
}
revealLayout();
}else if(view.getId() == R.id.share){
articleListener.OnShareClick(articles);
revealLayout();
}else if(view.getId() == R.id.title || view.getId() == R.id.thumbnail|| view.getId() == R.id.content) {
articleListener.OnItemClick(articles);
}
}
}
private void revealLayout() {
/*
MARGIN_RIGHT = 16;
FAB_BUTTON_RADIUS = 28;
*/
boolean isAttachedToWindow = ViewCompat.isAttachedToWindow(revealView);
if (isAttachedToWindow) {
int x = revealLayout.getRight();
int y = revealLayout.getBottom();
x -= ((28 * pixelDensity) + (16 * pixelDensity));
int hypotenuse = (int) Math.hypot(revealLayout.getWidth(), revealLayout.getHeight());
if (!flag) {
RelativeLayout.LayoutParams parameters = (RelativeLayout.LayoutParams)
revealView.getLayoutParams();
parameters.height = revealLayout.getHeight();
revealView.setLayoutParams(parameters);
Animator anim = ViewAnimationUtils.createCircularReveal(revealView, x, y, 0, hypotenuse);
anim.setDuration(200);
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationEnd(Animator animator) {
layoutButtons.setVisibility(View.VISIBLE);
layoutButtons.startAnimation(alphaAnimation);
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
revealView.setVisibility(View.VISIBLE);
anim.start();
flag = true;
} else {
Animator anim = ViewAnimationUtils.createCircularReveal(revealView, x, y, hypotenuse, 0);
anim.setDuration(200);
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
}
#Override
public void onAnimationEnd(Animator animator) {
revealView.setVisibility(View.GONE);
layoutButtons.setVisibility(View.GONE);
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
});
anim.start();
flag = false;
}
}
}
#Override
public void handleMessage(#NonNull LocalMessage localMessage) {
switch (localMessage.getId()){
case R.id.hide_reveal_layout:
int id = localMessage.getArg1();
if(flag && id != articles.getId()){
revealLayout();
}
break;
case R.id.recyclerview_scroll:
if(flag){
revealLayout();
}
break;
}
}
}
I keep getting an an error when trying to call WowZa GoCoder SDK's PlayerActivity and I am unable to understand the cause. The error appears when mStreamPlayerView.play(mStreamPlayerConfig, statusCallback) is called. Would really appreciate help on where i am going wrong
vodFragment.java
public class vodFragment extends Fragment {
private int mColumnCount = 1;
ListView videoView;
ArrayList <Vidoes> videoList;
private static String value;
String videoName;
String url = "http://192.168.43.149/twende/channelVOD.php";
public vodFragment() {
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (getActivity().getActionBar() != null) {
getActivity().getActionBar().setTitle(value);
}
View view = inflater.inflate(R.layout.fragment_vod_list, container, false);
videoView = (ListView) view.findViewById(R.id.listView);
videoList = new ArrayList<Vidoes>();
JSONObject channelInfo = new JSONObject();
try {
channelInfo.put("channelName", value);
channelInfo.put("channelOwner", "dan");
postJSONObject(url,channelInfo);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return view;
}
public static void setChannel(String channel){
value = channel;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
}
public void postJSONObject(final String myurl, final JSONObject parameters) {
class postJSONObject extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
loadIntoVodView(s);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected String doInBackground(Void... voids) {
HttpURLConnection conn = null;
try {
StringBuffer response = null;
URL url = new URL(myurl);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
writer.write(parameters.toString());
writer.close();
out.close();
int responseCode = conn.getResponseCode();
System.out.println("responseCode" + responseCode);
switch (responseCode) {
case 200:
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (conn != null) {
try {
conn.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
return null;
}
}
postJSONObject postJSONObject = new postJSONObject();
postJSONObject.execute();
}
private void loadIntoVodView(String json) throws JSONException {
JSONArray jsonArray = new JSONArray(json);
final String[] videos = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
videos[i] = removeExtension(obj.getString("title"));
Vidoes vidoe = new Vidoes();
vidoe.setTitle(videos[i]);
videoList.add(vidoe);
}
VideoListAdapter adapter = new VideoListAdapter(getActivity(), R.layout.vodparsedata, videoList);
videoView.setAdapter(adapter);
videoView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
videoName = Arrays.asList(videos).get(position);
Intent intent = new Intent(getActivity(), PlayerActivity.class);
String message = videoName+".mp4";
intent.putExtra("videoName", message);
startActivity(intent);
System.out.println("arr: " + Arrays.asList(videos).get(position));
}
});
}
public static String removeExtension(String fileName) {
if (fileName.indexOf(".") > 0) {
return fileName.substring(0, fileName.lastIndexOf("."));
} else {
return fileName;
}
}
}
PlayerActivity.java
public class PlayerActivity extends GoCoderSDKActivityBase {
final private static String TAG = PlayerActivity.class.getSimpleName();
String videoName;
private WOWZPlayerView mStreamPlayerView = null;
private WOWZPlayerConfig mStreamPlayerConfig = new WOWZPlayerConfig();
private MultiStateButton mBtnPlayStream = null;
private MultiStateButton mBtnSettings = null;
private MultiStateButton mBtnMic = null;
private MultiStateButton mBtnScale = null;
private SeekBar mSeekVolume = null;
private ProgressDialog mBufferingDialog = null;
private StatusView mStatusView = null;
private TextView mHelp = null;
private TimerView mTimerView = null;
private ImageButton mStreamMetadata = null;
private boolean mUseHLSPlayback = false;
private WOWZPlayerView.PacketThresholdChangeListener packetChangeListener = null;
private VolumeChangeObserver mVolumeSettingChangeObserver = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stream_player);
mRequiredPermissions = new String[]{};
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null) {
videoName= null;
} else {
videoName= extras.getString("videoName");
}
} else {
videoName= (String) savedInstanceState.getSerializable("videoName");
}
System.out.print(videoName);
mStreamPlayerConfig.setIsPlayback(true);
mStreamPlayerConfig.setHostAddress("192.168.43.149");
mStreamPlayerConfig.setApplicationName("Dark Souls 2 Channel");
mStreamPlayerConfig.setStreamName(videoName);
mStreamPlayerConfig.setPortNumber(1935);
mStreamPlayerView = (WOWZPlayerView) findViewById(R.id.vwStreamPlayer);
mBtnPlayStream = (MultiStateButton) findViewById(R.id.ic_play_stream);
mBtnSettings = (MultiStateButton) findViewById(R.id.ic_settings);
mBtnMic = (MultiStateButton) findViewById(R.id.ic_mic);
mBtnScale = (MultiStateButton) findViewById(R.id.ic_scale);
mTimerView = (TimerView) findViewById(R.id.txtTimer);
mStatusView = (StatusView) findViewById(R.id.statusView);
mStreamMetadata = (ImageButton) findViewById(R.id.imgBtnStreamInfo);
mHelp = (TextView) findViewById(R.id.streamPlayerHelp);
mSeekVolume = (SeekBar) findViewById(R.id.sb_volume);
WOWZStatusCallback statusCallback = new StatusCallback();
mStreamPlayerView.play(mStreamPlayerConfig, statusCallback);
mTimerView.setVisibility(View.GONE);
mStreamPlayerView.play(mStreamPlayerConfig, statusCallback);
if (sGoCoderSDK != null) {
/*
Packet change listener setup
*/
final PlayerActivity activity = this;
packetChangeListener = new WOWZPlayerView.PacketThresholdChangeListener() {
#Override
public void packetsBelowMinimumThreshold(int packetCount) {
WOWZLog.debug("Packets have fallen below threshold "+packetCount+"... ");
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Packets have fallen below threshold ... ", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void packetsAboveMinimumThreshold(int packetCount) {
WOWZLog.debug("Packets have risen above threshold "+packetCount+" ... ");
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Packets have risen above threshold ... ", Toast.LENGTH_SHORT).show();
}
});
}
};
mStreamPlayerView.setShowAllNotificationsWhenBelowThreshold(false);
mStreamPlayerView.setMinimumPacketThreshold(20);
mStreamPlayerView.registerPacketThresholdListener(packetChangeListener);
///// End packet change notification listener
mTimerView.setTimerProvider(new TimerView.TimerProvider() {
#Override
public long getTimecode() {
return mStreamPlayerView.getCurrentTime();
}
#Override
public long getDuration() {
return mStreamPlayerView.getDuration();
}
});
mSeekVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (mStreamPlayerView != null && mStreamPlayerView.isPlaying()) {
mStreamPlayerView.setVolume(progress);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// listen for volume changes from device buttons, etc.
mVolumeSettingChangeObserver = new VolumeChangeObserver(this, new Handler());
getApplicationContext().getContentResolver().registerContentObserver(android.provider.Settings.System.CONTENT_URI, true, mVolumeSettingChangeObserver);
mVolumeSettingChangeObserver.setVolumeChangeListener(new VolumeChangeObserver.VolumeChangeListener() {
#Override
public void onVolumeChanged(int previousLevel, int currentLevel) {
if (mSeekVolume != null)
mSeekVolume.setProgress(currentLevel);
if (mStreamPlayerView != null && mStreamPlayerView.isPlaying()) {
mStreamPlayerView.setVolume(currentLevel);
}
}
});
mBtnScale.setState(mStreamPlayerView.getScaleMode() == WOWZMediaConfig.FILL_VIEW);
// The streaming player configuration properties
mStreamPlayerConfig = new WOWZPlayerConfig();
mBufferingDialog = new ProgressDialog(this);
mBufferingDialog.setTitle(R.string.status_buffering);
mBufferingDialog.setMessage(getResources().getString(R.string.msg_please_wait));
mBufferingDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(R.string.button_cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
cancelBuffering(dialogInterface);
}
});
// testing player data event handler.
mStreamPlayerView.registerDataEventListener("onMetaData", new WOWZDataEvent.EventListener(){
#Override
public WOWZDataMap onWZDataEvent(String eventName, WOWZDataMap eventParams) {
String meta = "";
if(eventParams!=null)
meta = eventParams.toString();
WOWZLog.debug("onWZDataEvent -> eventName "+eventName+" = "+meta);
return null;
}
});
// testing player data event handler.
mStreamPlayerView.registerDataEventListener("onStatus", new WOWZDataEvent.EventListener(){
#Override
public WOWZDataMap onWZDataEvent(String eventName, WOWZDataMap eventParams) {
if(eventParams!=null)
WOWZLog.debug("onWZDataEvent -> eventName "+eventName+" = "+eventParams.toString());
return null;
}
});
// testing player data event handler.
mStreamPlayerView.registerDataEventListener("onTextData", new WOWZDataEvent.EventListener(){
#Override
public WOWZDataMap onWZDataEvent(String eventName, WOWZDataMap eventParams) {
if(eventParams!=null)
WOWZLog.debug("onWZDataEvent -> "+eventName+" = "+eventParams.get("text"));
return null;
}
});
} else {
mHelp.setVisibility(View.GONE);
mStatusView.setErrorMessage(WowzaGoCoder.getLastError().getErrorDescription());
}
}
#Override
protected void onDestroy() {
if (mVolumeSettingChangeObserver != null)
getApplicationContext().getContentResolver().unregisterContentObserver(mVolumeSettingChangeObserver);
super.onDestroy();
}
/**
* Android Activity class methods
*/
#Override
protected void onResume() {
super.onResume();
syncUIControlState();
}
#Override
protected void onPause() {
if (mStreamPlayerView != null && mStreamPlayerView.isPlaying()) {
mStreamPlayerView.stop();
// Wait for the streaming player to disconnect and shutdown...
mStreamPlayerView.getCurrentStatus().waitForState(WOWZState.IDLE);
}
super.onPause();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
public boolean isPlayerConfigReady()
{
return false;
}
/*
Click handler for network pausing
*/
public void onPauseNetwork(View v)
{
Button btn = (Button)findViewById(R.id.pause_network);
if(btn.getText().toString().trim().equalsIgnoreCase("pause network")) {
WOWZLog.info("Pausing network...");
btn.setText("Unpause Network");
mStreamPlayerView.pauseNetworkStack();
}
else{
WOWZLog.info("Unpausing network... btn.getText(): "+btn.getText());
btn.setText("Pause Network");
mStreamPlayerView.unpauseNetworkStack();
}
}
/**
* Click handler for the playback button
*/
public void onTogglePlayStream(View v) {
if (mStreamPlayerView.isPlaying()) {
mStreamPlayerView.stop();
} else if (mStreamPlayerView.isReadyToPlay()) {
if(!this.isNetworkAvailable()){
displayErrorDialog("No internet connection, please try again later.");
return;
}
// if(!this.isPlayerConfigReady()){
// displayErrorDialog("Please be sure to include a host, stream, and application to playback a stream.");
// return;
// }
mHelp.setVisibility(View.GONE);
WOWZStreamingError configValidationError = mStreamPlayerConfig.validateForPlayback();
if (configValidationError != null) {
mStatusView.setErrorMessage(configValidationError.getErrorDescription());
} else {
// Set the detail level for network logging output
mStreamPlayerView.setLogLevel(mWZNetworkLogLevel);
// Set the player's pre-buffer duration as stored in the app prefs
float preBufferDuration = GoCoderSDKPrefs.getPreBufferDuration(PreferenceManager.getDefaultSharedPreferences(this));
mStreamPlayerConfig.setPreRollBufferDuration(preBufferDuration);
// Start playback of the live stream
mStreamPlayerView.play(mStreamPlayerConfig, this);
}
}
}
/**
* WOWZStatusCallback interface methods
*/
#Override
public synchronized void onWZStatus(WOWZStatus status) {
final WOWZStatus playerStatus = new WOWZStatus(status);
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
WOWZStatus status = new WOWZStatus(playerStatus.getState());
switch(playerStatus.getState()) {
case WOWZPlayerView.STATE_PLAYING:
// Keep the screen on while we are playing back the stream
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
if (mStreamPlayerConfig.getPreRollBufferDuration() == 0f) {
mTimerView.startTimer();
}
// Since we have successfully opened up the server connection, store the connection info for auto complete
GoCoderSDKPrefs.storeHostConfig(PreferenceManager.getDefaultSharedPreferences(PlayerActivity.this), mStreamPlayerConfig);
// Log the stream metadata
WOWZLog.debug(TAG, "Stream metadata:\n" + mStreamPlayerView.getMetadata());
break;
case WOWZPlayerView.STATE_READY_TO_PLAY:
// Clear the "keep screen on" flag
WOWZLog.debug(TAG, "STATE_READY_TO_PLAY player activity status!");
if(playerStatus.getLastError()!=null)
displayErrorDialog(playerStatus.getLastError());
playerStatus.clearLastError();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mTimerView.stopTimer();
break;
case WOWZPlayerView.STATE_PREBUFFERING_STARTED:
WOWZLog.debug(TAG, "Dialog for buffering should show...");
showBuffering();
break;
case WOWZPlayerView.STATE_PREBUFFERING_ENDED:
WOWZLog.debug(TAG, "Dialog for buffering should stop...");
hideBuffering();
// Make sure player wasn't signaled to shutdown
if (mStreamPlayerView.isPlaying()) {
mTimerView.startTimer();
}
break;
default:
break;
}
syncUIControlState();
}
});
}
#Override
public synchronized void onWZError(final WOWZStatus playerStatus) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
displayErrorDialog(playerStatus.getLastError());
syncUIControlState();
}
});
}
public void onToggleMute(View v) {
mBtnMic.toggleState();
if (mStreamPlayerView != null)
mStreamPlayerView.mute(!mBtnMic.isOn());
mSeekVolume.setEnabled(mBtnMic.isOn());
}
public void onToggleScaleMode(View v) {
int newScaleMode = mStreamPlayerView.getScaleMode() == WOWZMediaConfig.RESIZE_TO_ASPECT ? WOWZMediaConfig.FILL_VIEW : WOWZMediaConfig.RESIZE_TO_ASPECT;
mBtnScale.setState(newScaleMode == WOWZMediaConfig.FILL_VIEW);
mStreamPlayerView.setScaleMode(newScaleMode);
}
public void onStreamMetadata(View v) {
WOWZDataMap streamMetadata = mStreamPlayerView.getMetadata();
WOWZDataMap streamStats = mStreamPlayerView.getStreamStats();
// WOWZDataMap streamConfig = mStreamPlayerView.getStreamConfig().toDataMap();
WOWZDataMap streamConfig = new WOWZDataMap();
WOWZDataMap streamInfo = new WOWZDataMap();
streamInfo.put("- Stream Statistics -", streamStats);
streamInfo.put("- Stream Metadata -", streamMetadata);
//streamInfo.put("- Stream Configuration -", streamConfig);
DataTableFragment dataTableFragment = DataTableFragment.newInstance("Stream Information", streamInfo, false, false);
getFragmentManager().beginTransaction()
.add(android.R.id.content, dataTableFragment)
.addToBackStack("metadata_fragment")
.commit();
}
public void onSettings(View v) {
// Display the prefs fragment
GoCoderSDKPrefs.PrefsFragment prefsFragment = new GoCoderSDKPrefs.PrefsFragment();
prefsFragment.setFixedSource(true);
prefsFragment.setForPlayback(true);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, prefsFragment)
.addToBackStack(null)
.commit();
}
private void syncUIControlState() {
boolean disableControls = (!(mStreamPlayerView.isReadyToPlay() || mStreamPlayerView.isPlaying()) || sGoCoderSDK == null);
if (disableControls) {
mBtnPlayStream.setEnabled(false);
mBtnSettings.setEnabled(false);
mSeekVolume.setEnabled(false);
mBtnScale.setEnabled(false);
mBtnMic.setEnabled(false);
mStreamMetadata.setEnabled(false);
} else {
mBtnPlayStream.setState(mStreamPlayerView.isPlaying());
mBtnPlayStream.setEnabled(true);
if (mStreamPlayerConfig.isAudioEnabled()) {
mBtnMic.setVisibility(View.VISIBLE);
mBtnMic.setEnabled(true);
mSeekVolume.setVisibility(View.VISIBLE);
mSeekVolume.setEnabled(mBtnMic.isOn());
mSeekVolume.setProgress(mStreamPlayerView.getVolume());
} else {
mSeekVolume.setVisibility(View.GONE);
mBtnMic.setVisibility(View.GONE);
}
mBtnScale.setVisibility(View.VISIBLE);
mBtnScale.setVisibility(mStreamPlayerView.isPlaying() && mStreamPlayerConfig.isVideoEnabled() ? View.VISIBLE : View.GONE);
mBtnScale.setEnabled(mStreamPlayerView.isPlaying() && mStreamPlayerConfig.isVideoEnabled());
mBtnSettings.setEnabled(!mStreamPlayerView.isPlaying());
mBtnSettings.setVisibility(mStreamPlayerView.isPlaying() ? View.GONE : View.VISIBLE);
mStreamMetadata.setEnabled(mStreamPlayerView.isPlaying());
mStreamMetadata.setVisibility(mStreamPlayerView.isPlaying() ? View.VISIBLE : View.GONE);
}
}
private void showBuffering() {
try {
if (mBufferingDialog == null) return;
mBufferingDialog.show();
}
catch(Exception ex){}
}
private void cancelBuffering(DialogInterface dialogInterface) {
if(mStreamPlayerConfig.getHLSBackupURL()!=null || mStreamPlayerConfig.isHLSEnabled()){
mStreamPlayerView.stop(true);
}
else if (mStreamPlayerView != null && mStreamPlayerView.isPlaying()) {
mStreamPlayerView.stop(true);
}
}
private void hideBuffering() {
if (mBufferingDialog.isShowing())
mBufferingDialog.dismiss();
}
#Override
public void syncPreferences() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
mWZNetworkLogLevel = Integer.valueOf(prefs.getString("wz_debug_net_log_level", String.valueOf(WOWZLog.LOG_LEVEL_DEBUG)));
mStreamPlayerConfig.setIsPlayback(true);
if (mStreamPlayerConfig != null)
GoCoderSDKPrefs.updateConfigFromPrefsForPlayer(prefs, mStreamPlayerConfig);
}
private class StatusCallback implements WOWZStatusCallback {
#Override
public void onWZStatus(WOWZStatus wzStatus) {
}
#Override
public void onWZError(WOWZStatus wzStatus) {
}
}
}
The error I get is;
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wowza.gocoder.sdk.sampleapp/com.wowza.gocoder.sdk.sampleapp.PlayerActivity}: java.lang.RuntimeException: Invalid surface: null
You start the stream in onCreate. At this time the Surface used by WOWZPlayerView is not ready yet and the app crashes with the 'Invalid surface' error.
If you look at the sample test in the GoCoder SDK, the playback is started when the user clicks a button. Eg. when the Surface is valid.
Create a button and move your 'mStreamPlayerView.play(mStreamPlayerConfig, statusCallback);' to the button.onClick.
Or ... use any GoCoder SDK v1.7 and more recent.
Please, let me know if I can help any further.
Thanks
I have a sliding image that extends pageradapter. At first it was working. But when i open new activity then press the back button the app is crashing and i've got this error :
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 10, found: 0 Pager id: malate.denise.chelsie.igphthesisbfinal:id/pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class malate.denise.chelsie.igphthesisbfinal.SlidingImage_Adapter
Here's my SlidingImage_Adapter.class
public class SlidingImage_Adapter extends PagerAdapter {
private ArrayList<Pictures> IMAGES;
private LayoutInflater inflater;
private Context context;
public SlidingImage_Adapter(Context context,ArrayList<Pictures> IMAGES) {
this.context = context;
this.IMAGES=IMAGES;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return IMAGES.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View imageLayout = inflater.inflate(R.layout.slidingimage_layout, view, false);
assert imageLayout != null;
final ImageView imageView = (ImageView) imageLayout
.findViewById(R.id.image);
new DownloadImageTask(imageView).execute(IMAGES.get(position).getPhotopath());
// imageView.setImageResource(IMAGES.get(position));
view.addView(imageLayout, 0);
return imageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
notifyDataSetChanged();
}
#Override
public Parcelable saveState() {
return null;
}
and my AttractionInfo.class
public class AttractionInfo extends ActionBarActivity implements View.OnClickListener {
TextToSpeech tts;
TextView nameofplace,location,exact_address,operatinghours,info;
String nameofplace_s,location_s,exact_address_s,operatinghours_s,info_s,latlang_s,path_s,category_s;
ImageView play,rate,addtoplan,map;
ArrayList<Pictures> records;
private static ViewPager mPager;
private static int currentPage = 0;
String line=null;
private static int NUM_PAGES = 0;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_attraction_info);
map = (ImageView)findViewById(R.id.map);
map.setOnClickListener(this);
records=new ArrayList<Pictures>();
nameofplace = (TextView) findViewById(R.id.nameofplace);
info = (TextView) findViewById(R.id.info);
exact_address = (TextView) findViewById(R.id.exact_address);
location = (TextView)findViewById(R.id.location);
operatinghours=(TextView)findViewById(R.id.operatinghours);
play = (ImageView) findViewById(R.id.play);
rate = (ImageView) findViewById(R.id.rate);
addtoplan = (ImageView)findViewById(R.id.addtoplan);
addtoplan.setOnClickListener(this);
Bundle extras = getIntent().getExtras();
play.setOnClickListener(this);
rate.setOnClickListener(this);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
getSupportActionBar().setDisplayShowTitleEnabled(false);
tts = new TextToSpeech(AttractionInfo.this, new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR){
tts.setLanguage(Locale.ENGLISH);
}
}
});
if (extras != null) {
nameofplace_s = extras.getString("name");
nameofplace.setText(nameofplace_s);
info_s = extras.getString("description");
info.setText(info_s);
exact_address_s = extras.getString("exactaddress");
exact_address.setText(exact_address_s);
location_s = extras.getString("location");
location.setText(location_s);
operatinghours_s=extras.getString("operatinghours");
operatinghours.setText(operatinghours_s);
latlang_s = extras.getString("latlang");
path_s=extras.getString("path");
category_s = extras.getString("category");
}
}
public void onStart() {
super.onStart();
fetchphoto bt = new fetchphoto();
bt.execute();
}
#Override
protected void onPause() {
if (tts != null){
tts.stop();
tts.shutdown();
}
super.onPause();
}
#Override
public void onClick(View v) {
if (v == play) {
String speech1 = nameofplace.getText().toString();
String speech2 = info.getText().toString();
String speech = speech1 + "." + speech2;
tts.speak(speech, TextToSpeech.QUEUE_FLUSH, null);
} else if (v==rate){
Intent myIntent = new Intent(this, ListOfReviews.class);
myIntent.putExtra("placename", nameofplace_s);
myIntent.putExtra("category",category_s);
startActivity(myIntent);
}else if(v==addtoplan){
Intent myIntent = new Intent(this, AddPlan.class);
myIntent.putExtra("placename", nameofplace_s);
myIntent.putExtra("category",category_s);
startActivity(myIntent);
}else if (v == map){
Intent myIntent = new Intent(this, Map.class);
myIntent.putExtra("placename", nameofplace_s);
myIntent.putExtra("category",category_s);
myIntent.putExtra("latlang",latlang_s);
myIntent.putExtra("address",exact_address_s);
myIntent.putExtra("path",path_s);
startActivity(myIntent);
}
}
private void init() {
SlidingImage_Adapter adapter = new SlidingImage_Adapter(this,records);
for(int i=0;i<records.size();i++){
Pictures pics = records.get(i);
String pic = pics.getPhotopath();
adapter.notifyDataSetChanged();
}
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(adapter);
CirclePageIndicator indicator = (CirclePageIndicator)
findViewById(R.id.indicator);
indicator.setViewPager(mPager);
final float density = getResources().getDisplayMetrics().density;
indicator.setRadius(5 * density);
NUM_PAGES =records.size();
// Auto start of viewpager
final Handler handler = new Handler();
final Runnable Update = new Runnable() {
public void run() {
if (currentPage == NUM_PAGES) {
currentPage = 0;
}
mPager.setCurrentItem(currentPage++, true);
}
};
Timer swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
},5000, 5000);
// Pager listener over indicator
indicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
currentPage = position;
}
#Override
public void onPageScrolled(int pos, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int pos) {
}
});
}
private class fetchphoto extends AsyncTask<Void, Void, Void> {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
protected void onPreExecute() {
super.onPreExecute();
}
protected Void doInBackground(Void... params) {
InputStream is = null;
String result = "";
nameValuePairs.add(new BasicNameValuePair("cityname", nameofplace_s));
try
{
records.clear();
HttpParams httpParams = new BasicHttpParams();
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://igph.esy.es/getphoto.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
Log.e("pass 1", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 1", e.toString());
}
try
{
BufferedReader reader = new BufferedReader
(new InputStreamReader(is,"utf-8"),8);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Log.e("pass 2", "connection success ");
}
catch(Exception e)
{
Log.e("Fail 2", e.toString());
}
//parse json data
try {
Log.i("tagconvertstr", "["+result+"]");
// Remove unexpected characters that might be added to beginning of the string
result = result.substring(result.indexOf(""));
JSONArray jArray = new JSONArray(result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
Pictures p = new Pictures();
p.setPhotoname(json_data.getString("photo_name"));
p.setPlacename(json_data.getString("place_name"));
p.setCategory(json_data.getString("category"));
p.setPhotopath(json_data.getString("path"));
records.add(p);
}
} catch (Exception e) {
Log.e("ERROR", "Error pasting data " + e.toString());
}
return null;
}
protected void onPostExecute(Void result) {
// if (pd != null) pd.dismiss(); //close dialog
Log.e("size", records.size() + "");
init();
}
}
}
I've red some similar problems and learned that adding notifychanged may solved the problem but i dont where to place it. Hope you can help m . thanks
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged()
so i'm working with a custom listView when you reach the final of the list i show a footer view and create a listener to implements on the Activity/Fragment that will use the listView. My problem is when i call a services on this method and update the array with the data of the adapter i received that error. I call too a services on the adapter because i need the data of the specific showing row.
Here go my code:
Custom listView:
public class EndlessListView extends ListView implements OnScrollListener {
private View footer;
private boolean isLoading;
private EndlessListener listener;
private ArrayAdapter<?> adapter;
private boolean isReachEnd;
public EndlessListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setOnScrollListener(this);
}
public EndlessListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnScrollListener(this);
}
public EndlessListView(Context context) {
super(context);
this.setOnScrollListener(this);
}
public void refreshList() {
this.removeFooterView(footer);
this.requestLayout();
adapter.notifyDataSetChanged();
isLoading = false;
}
public void setListener(EndlessListener listener) {
this.listener = listener;
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() == null)
return;
if (getAdapter().getCount() == 0)
return;
int l = visibleItemCount + firstVisibleItem;
if (l >= totalItemCount && !isLoading && !isReachEnd) {
// It is time to add new data. We call the listener
this.addFooterView(footer);
this.requestLayout();
isLoading = true;
listener.loadData();
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void setLoadingView(int resId) {
LayoutInflater inflater = (LayoutInflater) super.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
footer = (View) inflater.inflate(resId, null);
this.addFooterView(footer);
}
public void setAdapter(ArrayAdapter<?> adapter) {
super.setAdapter(adapter);
this.adapter = adapter;
this.removeFooterView(footer);
}
public void addNewData(ArrayList data) {
this.removeFooterView(footer);
this.requestLayout();
adapter.addAll(data);
adapter.notifyDataSetChanged();
isLoading = false;
}
public void removeFooter() {
if (adapter != null) {
this.removeFooterView(footer);
isLoading = false;
this.adapter.notifyDataSetChanged();
this.requestLayout();
}
}
public void addFooter() {
if (adapter != null) {
this.addFooterView(footer);
isLoading = true;
this.adapter.notifyDataSetChanged();
this.requestLayout();
}
}
public EndlessListener setListener() {
return listener;
}
public static interface EndlessListener {
public void loadData();
}
public boolean isReachEnd() {
return isReachEnd;
}
public void setReachEnd(boolean isReachEnd) {
this.isReachEnd = isReachEnd;
}
public boolean isLoading() {
return isLoading;
}
public void setLoading(boolean isLoading) {
this.isLoading = isLoading;
}
#Override
public ArrayAdapter<?> getAdapter() {
return adapter;
}
public View getFooter() {
return footer;
}
#Override
public void setClickable(boolean clickable) {
super.setClickable(clickable);
}}
Get data and update the array of the adapter:
public void getMatcher() {
try {
gettingMatcher = true;
Timber.i(getString(R.string.getting_mather));
HomeRequest.createMatcherRequest(getActivity(), new RequestController.ResponseListener<JSONObject>() {
#Override
public void onStart() {
((AuthorizedActivity) getActivity()).showProgress(true);
}
#Override
public void onResponse(JSONObject response) {
parseMatcher(response);
}
#Override
public void onError(int error, String message) {
gettingMatcher = false;
((AuthorizedActivity) getActivity()).showProgress(false);
Utils.showToast(getActivity(), getString(R.string.error_unexpected));
}
});
} catch (Exception e) {
gettingMatcher = false;
Timber.e(e, getString(R.string.error_getting_matcher));
Crashlytics.logException(e);
}
}
/**
* Parse the data from the web services and load the UI
*
* #param response
*/
private void parseMatcher(JSONObject response) {
MatcherResponse matcherResponse = new MatcherResponse(false, "");
ArrayList<User> auxDiscover = new ArrayList<>();
if (response == null) {
Timber.e(getString(R.string.error_empty_response));
Utils.showToast(getActivity(), getString(R.string.error_empty_response));
((AuthorizedActivity) getActivity()).showProgress(false);
gettingMatcher = false;
return;
}
try {
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
matcherResponse = gson.fromJson(response.toString(), MatcherResponse.class);
if (matcherResponse.isSuccess()) {
auxDiscover = matcherResponse.getDiscover();
if (auxDiscover.size() > 0) {
discoversData.addAll(auxDiscover);
adapter.notifyDataSetChanged();
discovers.removeFooter();
}
} else {
Timber.e(getString(R.string.error_parsing_matcher));
Utils.showToast(getActivity(), getString(R.string.error_unexpected));
}
gettingMatcher = false;
((AuthorizedActivity) getActivity()).showProgress(false);
} catch (Exception e) {
((AuthorizedActivity) getActivity()).showProgress(false);
gettingMatcher = false;
Timber.e(getString(R.string.error_parsing_matcher));
Crashlytics.logException(e);
}
}
Adapter:
public class DiscoverEndlessAdapter extends ArrayAdapter {
private ArrayList<User> itemList;
private Context ctx;
private static OnClickDiscoverEvents onClickDiscoverEvents;
private DiscoverFragment fragment;
public DiscoverEndlessAdapter(Context ctx, ArrayList<User> itemList, OnClickDiscoverEvents onClickDiscoverEvents, DiscoverFragment fragment) {
super(ctx, R.layout.adapter_discover, itemList);
this.itemList = itemList;
this.ctx = ctx;
this.onClickDiscoverEvents = onClickDiscoverEvents;
this.fragment = fragment;
}
#Override
public int getCount() {
return itemList.size();
}
#Override
public User getItem(int i) {
return itemList.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
return getDiscoverRow(position, convertView, parent, holder);
}
static class ViewHolder {
#InjectView(R.id.adapter_discover_title)
TextView title;
#InjectView(R.id.adapter_discover_subtitle)
TextView subTitle;
#InjectView(R.id.adapter_discover_avatar)
ImageView avatar;
#InjectView(R.id.adapter_discover_connect)
TextView connectWith;
#InjectView(R.id.adapter_discover_message)
ImageButton message;
#InjectView(R.id.adapter_discover_description)
TextView description;
#InjectView(R.id.adapter_discover_more)
ImageButton more;
#InjectView(R.id.adapter_discover_avatar_connection)
ImageView avatarConnection;
#InjectView(R.id.adapter_discover_avatar_connection_2)
ImageView avatarConnection2;
#InjectView(R.id.adapter_discover_avatar_connection_3)
ImageView avatarConnection3;
#InjectView(R.id.adapter_discover_avatar_connection_4)
ImageView avatarConnection4;
#InjectView(R.id.adapter_discover_connection_opacity)
TextView avatarConnectionOpacity;
#InjectView(R.id.adapter_discover_message)
ImageButton messageButton;
#InjectView(R.id.adapter_discover_more)
ImageButton optionButton;
/*OnClick*/
#OnClick(R.id.adapter_discover_message)
public void onGoChat(View view) {
onClickDiscoverEvents.showProfile(view);
}
#OnClick(R.id.adapter_discover_more)
public void onShowMoreOption(View view) {
onClickDiscoverEvents.showOption(view);
}
private Context ctx;
public ViewHolder(View view, Context ctx) {
ButterKnife.inject(this, view);
this.ctx = ctx;
}
}
/**
* Create the view for the chat data row
*
* #param position
* #param convertView
* #param parent
* #param holder
* #return
*/
private View getDiscoverRow(int position, View convertView, ViewGroup parent, ViewHolder holder) {
try {
User user = getItem(position);
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.adapter_discover, parent, false);
holder = new ViewHolder(convertView, ctx);
convertView.setTag(holder);
}
// Title
String title = Utils.getNameFromUser(user);
holder.title.setText(title);
// Subtitle
String subTitle = Utils.getRoleAndLocationFromUser(user);
holder.subTitle.setText(subTitle);
// Description
String description = user.getAccomplishment();
holder.description.setText(description);
//Avatar
Utils.setImageToImageViewFromUrl(ctx, holder.avatar, user.getImage(), user.getFirstName(), user.getLastName());
//ImageButtons
holder.more.setFocusable(false);
holder.message.setFocusable(false);
//CommonConnections
if (user.getCommonConnections() == null)
getCommonConnections(user.getId(), position);
else {
ArrayList<Connection> connections = user.getCommonConnections();
if (connections.size() > 0) {
if ((connections.size() > 0) && (holder.avatarConnection.getVisibility() != View.VISIBLE)) {
Connection connection = connections.get(0);
Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection, connection.getImage(), connection.getFirstName(), connection.getLastName());
holder.avatarConnection.setVisibility(View.VISIBLE);
}
if ((connections.size() > 1) && (holder.avatarConnection2.getVisibility() != View.VISIBLE)) {
Connection connection = connections.get(1);
Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection2, connection.getImage(), connection.getFirstName(), connection.getLastName());
holder.avatarConnection2.setVisibility(View.VISIBLE);
}
if ((connections.size() > 2) && (holder.avatarConnection3.getVisibility() != View.VISIBLE)) {
Connection connection = connections.get(2);
Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection3, connection.getImage(), connection.getFirstName(), connection.getLastName());
holder.avatarConnection3.setVisibility(View.VISIBLE);
}
if ((connections.size() > 3) && (holder.avatarConnection4.getVisibility() != View.VISIBLE)) {
Connection connection = connections.get(3);
Utils.setImageToImageViewFromUrl(ctx, holder.avatarConnection4, connection.getImage(), connection.getFirstName(), connection.getLastName());
holder.avatarConnection4.setVisibility(View.VISIBLE);
}
if ((connections.size() > 4) && (holder.avatarConnectionOpacity.getVisibility() != View.VISIBLE)) {
int quantity = connections.size() - 4;
String moreConnections = "+" + quantity;
if (quantity > 0) {
holder.avatarConnectionOpacity.setText(moreConnections);
holder.avatarConnectionOpacity.setVisibility(View.VISIBLE);
}
}
} else {
if (isCommon(user.getSkills())) {
holder.avatarConnection.setImageResource(R.drawable.ic_common_skill);
} else
holder.avatarConnection.setVisibility(View.GONE);
if (isCommon(user.getCompanies())) {
holder.avatarConnection2.setImageResource(R.drawable.ic_common_work);
} else
holder.avatarConnection2.setVisibility(View.GONE);
holder.avatarConnection3.setVisibility(View.GONE);
holder.avatarConnection4.setVisibility(View.GONE);
holder.avatarConnectionOpacity.setVisibility(View.GONE);
}
}
//Buttons
holder.messageButton.setTag(user);
holder.optionButton.setTag(user);
} catch (Exception e) {
Timber.e(e, ctx.getString(R.string.error_getview_discover_adapter));
Crashlytics.log(ctx.getString(R.string.error_getview_discover_adapter));
}
return convertView;
}
public void getCommonConnections(long caliberId, final int position) {
try {
Timber.i(ctx.getString(R.string.getting_common_connections));
HomeRequest.createCommonConnectionsRequest(ctx, caliberId, new RequestController.
ResponseListener<JSONObject>() {
#Override
public void onStart() {
}
#Override
public void onResponse(JSONObject response) {
parseCommonConnections(response, position);
}
#Override
public void onError(int error, String message) {
Toast.makeText(ctx, ctx.getString(R.string.error_unexpected), Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
Timber.e(e, ctx.getString(R.string.error_getting_common_connections));
Crashlytics.logException(e);
}
}
/**
* Parse the data from the web services and load the UI
*
* #param response
*/
private void parseCommonConnections(JSONObject response, int position) {
CommonConnectionsResponse commonConnectionsResponse = new CommonConnectionsResponse();
ArrayList<Connection> connections = new ArrayList<>();
if (response == null) {
Timber.e(ctx.getString(R.string.error_empty_response));
return;
}
try {
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
commonConnectionsResponse = gson.fromJson(response.toString(), CommonConnectionsResponse.class);
if (commonConnectionsResponse.isSuccess()) {
itemList.get(position).setCommonConnections(commonConnectionsResponse.getConnections().getConnections());
fragment.discoversData.get(position).setCommonConnections(commonConnectionsResponse.getConnections().getConnections());
} else {
itemList.get(position).setCommonConnections(new ArrayList<Connection>());
fragment.discoversData.get(position).setCommonConnections(new ArrayList<Connection>());
Timber.i(ctx.getString(R.string.no_common_connections, Utils.getNameFromUser(fragment.discoversData.get(position))));
}
notifyDataSetChanged();
} catch (Exception e) {
Timber.e(ctx.getString(R.string.error_parsing_common_connections));
Crashlytics.logException(e);
}
}
/**
* Return common value of skill or company object from list
*
* #param list
* #return
*/
private boolean isCommon(ArrayList<?> list) {
if ((list != null) && (list.size() > 0)) {
for (int i = 0; i < list.size(); i++) {
Object object = list.get(i);
if (object instanceof Skill) {
if (((Skill) object).isCommon())
return true;
} else if (object instanceof Company) {
if (((Company) object).isCommon())
return true;
} else
return false;
}
} else
return false;
return false;
}
}
Any help would be greatly appreciated.
You can try to call setAdapter(null) before modifying data inside the Adapter.