Get currentItem of (Vertical)ViewPager - java

I have an app with vertical slider to switch between different smileys (from happier to saddest)
My problem is i don't know how I can get currentItem of my ViewPager (When User is on a specific smiley)
I've tried
verticalViewPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mPreferences.edit().putInt(PREF_KEY_CURRENT_SMILEY,verticalViewPager.getCurrentItem()).apply();
return false;
}
});
And in the other activity (where i have to store the current smiley selected) :
currentSmileyInt = mPreferences.getInt(PREF_KEY_CURRENT_SMILEY,-50);
currentSmileyString = Integer.toString(currentSmileyInt);
currentSmileyTextView.setText(currentSmileyString);
If i'm good the textview on the other activity should display an int between 1-6. (different positions), and if i'm not good it display -50.
I don't understand what i'm doing wrong, as i set verticalVP.setCurrentItem(3) the corresponding smiley is displayed ...
Thank you in advance and sorry for my bad english :)

**You can use ViewPager.OnPageChangeListener**
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
final SharedPreferences.Editor editor = pref.edit();
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener(){
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
currentPage=position;
Toast.makeText(MainAsyncActivity.this, "position: "+position, Toast.LENGTH_SHORT).show();
editor.putInt("key_name",currentPage); // Storing integer
editor.commit(); // commit changes
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
**get stored value from SharedPreferences**
int currentSmileyInt= pref.getInt("key_name", 0);
Log.d("Keyname: ", String.valueOf(currentSmileyInt));
String currentSmileyString = Integer.toString(currentSmileyInt);
currentSmileyTextView.setText(currentSmileyString);

why don't you just use getcurrentItem method from viewpager. like following, will give you the pageNumber of the view pager.
// getting current Page
int page = mPager.getCurrentItem();

This method getCurrentItem will work for you to get a position of ViewPager fragment and you can use like this following:
((YourActivity)getActivity()).verticalViewPager.getCurrentItem());
YourActivityis where you are exactly using the ViewPager with adapter and getActivity() is the Context as a reference of your fragment and do not forget to make verticalViewPager object as public access specifier.

Related

Set visibility TableLayout based item selected on Spinner

I want to make Spinner to set Visibility of table, i have 2 Array String "cuboid and cylinder". if i select Cuboid , cubeT table is visible and cyclinderT table is Invisible. and if i select Cylinder , cylinderT table is Visible and cubeT is Invisible.
Sample code welcome. Thank you for your time.
You can set an OnItemSelectedListener to your Spinner then using the int position argument to decide what action to take.
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
switch (position) {
case Cuboid:
cubeT.setVisibility(View.VISIBLE);
cylinderT.setVisibility(View.GONE);
break;
....
}
}
#Override
public void onNothingSelected(AdapterView<?> parentView) { }
});
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
String text = ((Spinner)spinner).getSelectedItem().toString();
if (Intrinsics.areEqual(text, "Cuboid")) {
//Your code here to set your "table" as cubeT if it's image in imageview
//if it's a "tableLayout" you may create 2 different layouts included and..:
setContentView(R.layout.your_cubeT_layout);
} else if (Intrinsics.areEqual(text, "Cylinder")) {
setContentView(R.layout.your_cyclinderT_layout);
}
} //when it comes to use different layouts on the same activity, generally suggestions made over fragments to make your code more dynamic but i don't know how to do that...
#Override
public void onNothingSelected(AdapterView<?> parentView) {
// your code here
}
});
I'm not using java since years so i might code bad... So no warranty!

Shared Element Transition is not exiting properly

I have fragment from which I'm launching activity with shared element transition that has viewpager in it, the enter transition works fine but when i scroll in view pager and finish transition the shared image comes from left side which is not desired it should reposition itself to where it was launched, here is my code:
Intent myIntent = new Intent(getActivity(), EnlargeActivity.class);
ActivityOptionsCompat options = ActivityOptionsCompat.
makeSceneTransitionAnimation(getActivity(),
imageView,
ViewCompat.getTransitionName(imageView));
startActivity(myIntent, options.toBundle());
I'm updating view and its name in activity that contains viewpager when finishing activity, but its going with blink:
public void finishAfterTransition() {
setEnterSharedElementCallback(new SharedElementCallback() {
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
// Clear all current shared views and names
names.clear();
sharedElements.clear();
ViewGroup viewGroup = (ViewGroup) viewPagerDetail.getAdapter()
.instantiateItem(viewPagerDetail, viewPagerDetail.getCurrentItem());
if (viewGroup == null) {
return;
}
// Map the first shared element name to the child ImageView.
sharedElements.put(viewGroup.findViewById(R.id.img).getTransitionName(), viewGroup.findViewById(R.id.img));
// setExitSharedElementCallback((SharedElementCallback) this);
}
});
super.finishAfterTransition();
Basically, Android start the transition with your pre-defined View and transitionName and automatically use the same properties for the return transition. When you change your focused View in ViewPager, Android doesn't know about that and keep the transition on the previous one on its way back. So you need to inform Android about the changes:
Remap the transition properties: Use setEnterSharedElementCallback to change the transitionName and View to the new one before returning from Activity2.
Wait for the Activity1 to finish rendering addOnPreDrawListener.
It's a bit complex in the final implementation. But you can look at my sample code https://github.com/tamhuynhit/PhotoGallery. I try to implement the shared-element-transition from many simple to complex sections.
Your problem appeared from Level 3 and solved in Level 4.
I am writing a tutorial about this but it's not in English so hope the code can help
UPDATE 1: Work flow
Here is how I implement it in my code:
Override finishAfterTransition in Activity2 and call setEnterSharedElementCallback method to re-map the current selected item in ViewPager. Also, call setResult to pass the new selected index back to previous activity here.
#Override
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void finishAfterTransition() {
setEnterSharedElementCallback(new SharedElementCallback() {
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
View selectedView = getSelectedView();
if (selectedView == null)
return;
// Clear all current shared views and names
names.clear();
sharedElements.clear();
// Store new selected view and name
String transitionName = ViewCompat.getTransitionName(selectedView);
names.add(transitionName);
sharedElements.put(transitionName, selectedView);
setExitSharedElementCallback((SharedElementCallback) null);
}
});
Intent intent = new Intent();
intent.putExtra(PHOTO_FOCUSED_INDEX, mCurrentIndex);
setResult(RESULT_PHOTO_CLOSED, intent);
super.finishAfterTransition();
}
Write a custom ShareElementCallback so I can set the callback before knowing which View is going to be used.
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static class CustomSharedElementCallback extends SharedElementCallback {
private View mView;
/**
* Set the transtion View to the callback, this should be called before starting the transition so the View is not null
*/
public void setView(View view) {
mView = view;
}
#Override
public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
// Clear all current shared views and names
names.clear();
sharedElements.clear();
// Store new selected view and name
String transitionName = ViewCompat.getTransitionName(mView);
names.add(transitionName);
sharedElements.put(transitionName, mView);
}
}
Override onActivityReenter in Activity1, get the selected index from the result Intent. Set setExitSharedElementCallback to re-map new selected View when the transition begins.Call supportPostponeEnterTransition to delay a bit because your new View may not be rendered at this point. Use getViewTreeObserver().addOnPreDrawListener to listen for the layout changes, find the right View by the selected index and continue the transition supportStartPostponedEnterTransition.
#Override
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void onActivityReenter(int resultCode, Intent data) {
if (resultCode != LevelFourFullPhotoActivity.RESULT_PHOTO_CLOSED || data == null)
return;
final int selectedIndex = data.getIntExtra(LevelFourFullPhotoActivity.PHOTO_FOCUSED_INDEX, -1);
if (selectedIndex == -1)
return;
// Scroll to the new selected view in case it's not currently visible on the screen
mPhotoList.scrollToPosition(selectedIndex);
final CustomSharedElementCallback callback = new CustomSharedElementCallback();
getActivity().setExitSharedElementCallback(callback);
// Listen for the transition end and clear all registered callback
getActivity().getWindow().getSharedElementExitTransition().addListener(new Transition.TransitionListener() {
#Override
public void onTransitionStart(Transition transition) {}
#Override
public void onTransitionPause(Transition transition) {}
#Override
public void onTransitionResume(Transition transition) {}
#Override
public void onTransitionEnd(Transition transition) {
removeCallback();
}
#Override
public void onTransitionCancel(Transition transition) {
removeCallback();
}
private void removeCallback() {
if (getActivity() != null) {
getActivity().getWindow().getSharedElementExitTransition().removeListener(this);
getActivity().setExitSharedElementCallback((SharedElementCallback) null);
}
}
});
// Pause transition until the selected view is fully drawn
getActivity().supportPostponeEnterTransition();
// Listen for the RecyclerView pre draw to make sure the selected view is visible,
// and findViewHolderForAdapterPosition will return a non null ViewHolder
mPhotoList.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
mPhotoList.getViewTreeObserver().removeOnPreDrawListener(this);
RecyclerView.ViewHolder holder = mPhotoList.findViewHolderForAdapterPosition(selectedIndex);
if (holder instanceof ViewHolder) {
callback.setView(((ViewHolder) holder).mPhotoImg);
}
// Continue the transition
getActivity().supportStartPostponedEnterTransition();
return true;
}
});
}
UPDATE 2: getSelectedItem
To get selected View from the ViewPager, don't use getChildAt or you get the wrong View, use findViewWithTag instead
In the PagerAdapter.instantiateItem, use position as tag for each View:
#Override
public View instantiateItem(ViewGroup container, int position) {
// Create the View
view.setTag(position)
// ...
}
Listen to onPageSelected event to get the selected index:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mSelectedIndex = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Call getSelectedView to get the current view by the selected index
private View getSelectedView() {
try {
return mPhotoViewPager.findViewWithTag(mSelectedIndex);
} catch (IndexOutOfBoundsException | NullPointerException ex) {
return null;
}
}
This is actually a default behavior, I was struggling SharedElementTransitions a lot, but I have nested fragments. I got my solution from an article (very recent article), it shows an implementation with a RecyclerView, which I assume you have. In short, the solution is to override onLayoutChange :
recyclerView.addOnLayoutChangeListener(
new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View view,
int left,
int top,
int right,
int bottom,
int oldLeft,
int oldTop,
int oldRight,
int oldBottom) {
recyclerView.removeOnLayoutChangeListener(this);
final RecyclerView.LayoutManager layoutManager =
recyclerView.getLayoutManager();
View viewAtPosition =
layoutManager.findViewByPosition(MainActivity.currentPosition);
// Scroll to position if the view for the current position is null (not
// currently part of layout manager children), or it's not completely
// visible.
if (viewAtPosition == null
|| layoutManager.isViewPartiallyVisible(viewAtPosition, false, true)){
recyclerView.post(()
-> layoutManager.scrollToPosition(MainActivity.currentPosition));
}
}
});
Here is the article, and you will also find the project on GitHub.

how can I start an app with last closed settings?

In my code, there are Spinners for countries and their cities. When I start app, the lists of Spinners are ordering alphabetically.
The application will be opened with the last closed settings. For example:
If we select France for country and Paris for city from spinners.
Then, exit from app. Start again. First element of state_spin will be France, city_spin will be Paris.
how can I do it. thanks..
state_spin = (Spinner) findViewById(R.id.spinner1);
city_spin = (Spinner) findViewById(R.id.spinner2);
new spinner1_countries(context,UrlMain,arrayAdpt_state,state_spin).execute();
//to get state lists from a website
state_spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
final String[] stateList = spinner1_countries.stateList;
new spinner2_city(context, arrayAdpt_state,city_spin).execute(); //to get city lists
}
public void onNothingSelected(AdapterView<?> arg0) { } });
city_spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
......
You can store the previously selected options in SharedPreferences. When your app starts again, load these default values from SharedPreferences and set them as default for your selectors.
Find a nice tutorial here
When the User selects something in the spinner, save the position to SharedPreferences:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
...
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("1st_spinner", position);
editor.apply();
}
When Your app is started get the position an set the spinner:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
int position = sp.getInt("1st_spinner", 1);
state_spin.setSelection(position);

Doing stuff in main activity from PreferenceActivity?

I have this line info.setTextSize(TypedValue.COMPLEX_UNIT_SP, number_config); below my cases in onItemSelected for a spinner. (it sets the textsize of an EditText with a value set with the spinner)
Then I have a preferences activity, in which I have a switchpreference, and I would like the above line to be "active" when the switch is set to "On" and inactive when it's set to off. So the textsize does not change when it's set to off. How would you do this?
Thank you very much
My spinners onItemSelected:
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
switch (position) {
case 0:
config_textsize = "10.0f".toString();
break;
case 1:
config_textsize = "12.0f".toString();
break;
...
}
String number_config = Float.valueOf(config_textsize);
/*This line */ EditText info.setTextSize(TypedValue.COMPLEX_UNIT_SP, number_config);
}
Preferences Activity:
public class Settings extends PreferenceActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
}
}
This is my switchpreference in xml:
<SwitchPreference
android:key="EditTextSize"
android:title="Text Size"
android:summary="Change text size when editing" />
Try:
this should return true if switched on or false if not. It´s only an assumption, I had never used SwitchPreference, but try it...
EDIT
create a method which returns integer:
private int getPosition(){
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(YourActivity.this);
boolean switchOn = prefs.getBoolean("EditTextSize",
false);
int position=-1;
if(switchOn==false){
position=0;
}else if(switchOn==true){
position=1
}
return position;}

Set text size of a TextView with value selected from a Spinner, on button click

I would like to set a value with a spinner, and then in my onClick method set the text size of a Remote View TextView (on a widget) to the selected value. How would I do this?
Thanks
I have tried:
String selected;
Context context = WidgetConfig.this;
static Spinner spinner;
...
spinner.setOnItemSelectedListener(this);
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
Log.v(TAG, "OnItemselected started");
switch (position) {
case 0:
selected = "10".toString();
Break;
}
}
public void onNothingSelected(AdapterView<?> arg0) {
}
View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
Log.v(TAG, "set remote view");
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
Log.v(TAG, "set txt size");
/* without this line*/ float number = Float.valueOf(selected.toString());
/* and this line, it runs fine */ views.setFloat(R.id.tvConfigInput, "setTextSize", number);
...
}
};
UPDATE:
I declared the string twice, so i fixed that, and now it's not crashing, but it not working.
The text size isn't changing.. what to do?
your string selected is null, you did define the selected string in a scope instead of a global var. Change it and it should work
String selected = "0"; // defined outside the function scope
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
Log.v(TAG, "OnItemselected started");
switch (position) {
case 0:
selected = "10".toString();
Break;
}
}
float number = Float.valueOf(selected);
Your answer is in the following:
Line 254 in WidgetConfig.java is calling a method on a null object.
11-20 21:07:29.018: E/AndroidRuntime(2547): java.lang.NullPointerException
11-20 21:07:29.018: E/AndroidRuntime(2547): at com.harteg.NotesWidgetPro.WidgetConfig$1.onClick(WidgetConfig.java:254)

Categories

Resources