I have this code:
hubSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
final MediaPlayer mp2 = MediaPlayer.create(Textbox.this, R.raw.hero);
mp2.start();
}
public void onNothingSelected(AdapterView<?> parentView) {
}
});
(The code basically runs when a new item is selected of a spinner and then plays a song, which later will be a variable based on what was picked, but I'm fine as it is for now).
Problem: I want to be able to use 'mp2' out of this public void, (I want a button which pauses it). How can I do this?
Move the variable mp2 to the instance of the parent class. This will keep a running reference to it which you can interact with whenever you please. You will need to remove the final qualifier though if MediaPlayer.create(...) will be called more than once and stored.
edit:
I was referring to something along the lines of this:
class SomeClass {
private MediaPlayer mp2 = null;
private void whateverFunctionYouAreIn() {
hubSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
SomeClass.this.mp2 = MediaPlayer.create(Textbox.this, R.raw.hero);
SomeClass.this.mp2.start();
}
public void onNothingSelected(AdapterView<?> parentView) {}
});
//TODO: put this in an onClickListener:
if (this.mp2 != null) {
this.mp2.pause();
}
}
}
I'm not sure what happens when you call MediaPlayer.create(Textbox.this, R.raw.hero), but assuming it has no immediate effects, you can just create the object outside of the listener.
Edit1: OK, then how about this?
MediaPlayer currentPlayer;
methodA()
{
hubSpinner.setOnItemSelectedListener(new OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id)
{
MediaPlayer mp2 = MediaPlayer.create(Textbox.this, R.raw.hero);
mp2.start();
setPlayer(mp2);
}
public void onNothingSelected(AdapterView<?> parentView) {
}
});
setMediaPlayer(MediaPlayer player)
{
currentPlayer = player;
}
Related
I am showing random images in gridview using string array urls with picasso in first activity and when I'm clicking on any image in gridview then I want to show that exact random image in next activity. i am using put extra and sending that position like int r = random.nextInt(array.length); I'm using that r into gridview put extra as position. but when i m setting that r in imageview its showing another random image not exact.
This is my code
public class MainActivity extends Activity {
static Random random;
private GridView photoGrid;
private int mPhotoSize, mPhotoSpacing;
static int p;
// Some items to add to the GRID
static final String[] icons= {
"https://abhiandroid.com/ui/wp-content/uploads/2015/12/horizontalSpacing-in-Gridview.jpg",
"http://www.whatsappstatusmessages.com/wp-content/uploads/2017/01/whatsapp-dp-images-in-english.jpg",
"http://www.sarkarinaukrisearch.in/wp-content/uploads/2019/02/whatsapp-dp-status-in-english-1-77.jpg",
"https://www.trueshayari.in/wp-content/uploads/2018/07/Love-Status-DP-for-Couple.jpg",
"https://4.bp.blogspot.com/-2iawNx83Kpw/XL21pPj0aPI/AAAAAAAAKiE/VRR7pupbWDUj0TNNAKdGH8Baaz_c9IcSgCLcBGAs/s1600/ss.jpg",
"https://www.trueshayari.in/wp-content/uploads/2018/07/Love-Status-DP-for-Couple.jpg",
"https://3.bp.blogspot.com/-8us6YRiZEh0/XL21c6ibbXI/AAAAAAAAKh4/eNyjErq7q04YCeWxDPWojYfOoAC8BCodwCLcBGAs/s1600/s.jpg"
};
GridView gridView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = findViewById(R.id.albumGrid);
CustomAdopter customAdopter=new CustomAdopter();
gridView.setAdapter(customAdopter);
gridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this, SwipeView.class);
intent.putExtra("id", p);
startActivity(intent);
}
});
}
private static class CustomAdopter extends BaseAdapter {
static int p;
#Override
public int getCount() {
return icons.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = getLayoutInflater().inflate(R.layout.phototem, null);
ImageView imageView = view.findViewById(R.id.cover);
random = new Random(); // or create a static random field...
p= random.nextInt(icons.length);
Picasso.get().load(icons[p]).placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher).into(imageView);
return view;
}
}
Showing Image in this Activity
public class SwipeView extends Activity
{
int positions;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe_view);
// get intent data
Intent i = getIntent();
// Selected image id
positions = i.getExtras().getInt("id");
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
ImagePagerAdapter adapter = new ImagePagerAdapter();
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(technoapps4.goodnightshayariworld.MainActivity.p);
}
private class ImagePagerAdapter extends PagerAdapter
{
String[] icons =MainActivity.icons ;
#Override
public int getCount()
{
return icons.length;
}
#Override
public boolean isViewFromObject(View view, Object object)
{
return view == ((ImageView) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position)
{
Context context = SwipeView.this;
ImageView imageView = new ImageView(context);
Picasso.get().load(icons[position]).into(imageView);
container.addView(imageView, 0);
return imageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object)
{
container.removeView((ImageView) object);
}
}
}
For this purpose, you should create an Interface and pass the random position though that interface.
And the variable p isn't the clicked item position. The value of p is changing continuously while the gridView is populating items.
Edit:
Create an Interface like this:
public interface ItemClickListener {
void onItemClick(int position);
}
Now initialize the ItemClickListener instance inside your CustomAdopter class using the public setter.
public void setItemClickListener(ItemClickListener clickListener) {
onItemClickListener = clickListener;
}
and finally, add the following code inside the getview method to pass your adapter position to the listener.
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemClickListener.onItemClick(p);
}
});
Now instead of GridView's OnItemClickListener(), use this interface to get the correct position. like this-
gridView.setAdapter(customAdopter);
customAdopter.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(int position) {
Intent intent = new Intent(MainActivity.this, SwipeView.class);
intent.putExtra("id", position);
startActivity(intent);
}
});
I was going to provide you an alternative to this issue which is to use a recyclerview with gridLayoutManager and create a Custom layout that implements RecyclerView.Adapter....All of this might seem confusing to you I guess, so I quickly create a Unit Test to simulate what your code wants to achieve and below is the result.
public class ExampleUnitTest {
private static String data = null;
#Test
public void setParentData(){
data = "I set You";
Subclass subclass = new Subclass();
subclass.getParentData();
}
private static class Subclass{
void getParentData(){
assertEquals("I set You", data);
}
}
}
//Tests passed
I will take a minute to explain this, since you have your custom adapter as a subclass of MainActivity, then I believe that the subclass should have access to some values of its parent class.
I am talking about this: static int p; so you don't need to create two of that like you created in the subclass also which is the CustomAdopter class.
So below is the modification to your code and I believe it should work as far as the test passed, else, pls let me know so I can take a look again.
This is not really an answer but it's the only way I can share code and explain some things in details.
public class MainActivity extends Activity {
static Random random;
private GridView photoGrid;
private int mPhotoSize, mPhotoSpacing;
static int p;
// Some items to add to the GRID
static final String[] icons= {
"https://abhiandroid.com/ui/wp-content/uploads/2015/12/horizontalSpacing-in-Gridview.jpg",
"http://www.whatsappstatusmessages.com/wp-content/uploads/2017/01/whatsapp-dp-images-in-english.jpg",
"http://www.sarkarinaukrisearch.in/wp-content/uploads/2019/02/whatsapp-dp-status-in-english-1-77.jpg",
"https://www.trueshayari.in/wp-content/uploads/2018/07/Love-Status-DP-for-Couple.jpg",
"https://4.bp.blogspot.com/-2iawNx83Kpw/XL21pPj0aPI/AAAAAAAAKiE/VRR7pupbWDUj0TNNAKdGH8Baaz_c9IcSgCLcBGAs/s1600/ss.jpg",
"https://www.trueshayari.in/wp-content/uploads/2018/07/Love-Status-DP-for-Couple.jpg",
"https://3.bp.blogspot.com/-8us6YRiZEh0/XL21c6ibbXI/AAAAAAAAKh4/eNyjErq7q04YCeWxDPWojYfOoAC8BCodwCLcBGAs/s1600/s.jpg"
};
GridView gridView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = findViewById(R.id.albumGrid);
random = new Random(); // or create a static random field...
p= random.nextInt(icons.length);
CustomAdopter customAdopter=new CustomAdopter();
gridView.setAdapter(customAdopter);
gridView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(MainActivity.this, SwipeView.class);
intent.putExtra("id", p);
startActivity(intent);
}
});
}
private static class CustomAdopter extends BaseAdapter {
#Override
public int getCount() {
return icons.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = getLayoutInflater().inflate(R.layout.phototem, null);
ImageView imageView = view.findViewById(R.id.cover);
Picasso.get().load(icons[p]).placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher).into(imageView);
return view;
}
}
I'm trying to highlight my selected item in recyclerView when it's clicked.But it triggers two items instead. Please help me. Should i store clicked items as arraylist and clear them on new one clicked?
public class StationsAdapter extends RecyclerView.Adapter<StationsHolder> {
List<Station> stations;
public StationsAdapter(List<Station> stations){
this.stations = stations;
}
public void changeItemAtPosition(int position) {
notifyItemChanged(position);
}
#Override
public StationsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new StationsHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.stations_item,parent,false));
}
#Override
public void onBindViewHolder(StationsHolder holder, int position) {
bind(holder);
}
private void bind(final StationsHolder holder) {
holder.tvTitle.setText(stations.get(holder.getAdapterPosition()).getName());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.tvTitle.setTextColor(ContextCompat.getColor(AppDelegate.getContext(),R.color.colorAccent));
}
});
}
#Override
public int getItemCount() {
return stations.size();
}
}
This is due to recycler reusing the same view when you scroll. In order to fix that, you will have to do the next:
Store the selected item when you click on it. In a variable or in an array if you want more than one item
Check the selected item variable/array in the bind method to know if you have to color it or not
That way it will work flawlessly
After a thorough search and quite a lot of thinking, I couldn't find a solution to the following problem in AndroidStudio:
I have 2 spinners (input and output). I want to pass the value of the input spinner to a method that is called upon selection of a value of the output spinner (onItemSelected). The regarding code passage looks as follows:
private void setupSpinnerListeners() {
spinnerLengthInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String itemSelectedInSpinnerLengthInput = parent.getItemAtPosition(position).toString();
checkIfConvertingFromMeter(itemSelectedInSpinnerLengthInput);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spinnerLengthOutput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String itemSelectedInSpinnerLengthOutput = parent.getItemAtPosition(position).toString();
updateOutputTextfield(itemSelectedInSpinnerLengthInput, itemSelectedInSpinnerLengthOutput);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
I want the String itemSelectedInSpinnerLengthInput (that gets its value from the input spinner) to be available in the onItemSelected method of the output spinner. How to accomplish this?
Any help is greatly appreciated.
EDIT: Create a global variable INSIDE the setupSpinnerListeners Method, that is an array with length 1. The it'll work as I had intended.
I recommend you to use OnItemSelectedListener.
Then create a globalVariable to get the String to your first Spinner as follows :
String FirstValue = "";
Then you'll need to call this :
spinnerLengthInput.setOnItemSelectedListener(this);
spinnerLengthOutput.setOnItemSelectedListener(this);
Of course you'll need to implements OnItemSelectedListener
Then inside you can do the same that you were doing.
#Override
public void onItemSelected(AdapterView<?> spinner, View view, int position,long id)
{
FirstValue = spinner.getItemAtPosition(position).toString();
checkIfConvertingFromMeter(itemSelectedInSpinnerLengthInput);
}
Then in your other Spinner use the FirstValue value.
You should change itemSelectedInSpinnerLengthOutput as a global variable. After that, you can easy access to it in the onItemSelected method of the output spinner
String itemSelectedInSpinnerLengthInput; // global variable
private void setupSpinnerListeners() {
spinnerLengthInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
itemSelectedInSpinnerLengthInput = parent.getItemAtPosition(position).toString();
checkIfConvertingFromMeter(itemSelectedInSpinnerLengthInput);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spinnerLengthOutput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String itemSelectedInSpinnerLengthOutput = parent.getItemAtPosition(position).toString();
if(itemSelectedInSpinnerLengthInput != null){
updateOutputTextfield(itemSelectedInSpinnerLengthInput, itemSelectedInSpinnerLengthOutput);
}else{
Toast.makeText(getApplicationContext(), "please select input", Toast.LENGTH_LONG).show();
...
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
Hope this help
I'm trying to make two side by side ListViews act like a GridView to an extent. The reason I'm not using GridView is because there's no support for a Staggered Look. Anyways, I have the following code so far:
<- Old,now irrelevant code ->
EDIT:
I did as #Sam suggested and used the following code:
lv1.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (touchSource == null) {
touchSource = v;
}
if (v == touchSource) {
lv2.dispatchTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
clickSource = v;
touchSource = null;
}
}
return false;
}
});
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (parent == clickSource) {
//my own code here
}
}
});
lv1.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (view == clickSource) {
}
boolean loadMore = /* maybe add a padding */
firstVisibleItem + visibleItemCount + 10 >= totalItemCount;
if (loadMore) {
//add items, load more
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
});
lv2.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (touchSource == null) {
touchSource = v;
}
if (v == touchSource) {
lv1.dispatchTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
clickSource = v;
touchSource = null;
}
}
return false;
}
});
lv2.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (parent == clickSource) {
}
}
});
lv2.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (view == clickSource) {
}
boolean loadMore = /* maybe add a padding */
firstVisibleItem + visibleItemCount + 2 >= totalItemCount;
if (loadMore) {
}
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
});
I am also using a header on one of the lists to create a Staggered Effect and I need to keep this stagger at all costs. This is mostly working (the above code) but it unsyncs a lot of the time. I have figured out this is only when I have small short swipes. I'm not sure why, and I can't find a good solution. It seems to me that the above logic should work.
Also, just in case it matters, I am using UniversalImageLoader to load photos and a simple EndlessScroll logic to load more photos (directly calling adapter.notifyDataSetChanged()). This stuff doesn't seem too relevant though. Even when photos are loaded, I can still see it unsyncing.
I want to be clear: if I do short swipes (and sometimes just in general repeated scrolling) I can unsync the lists at will.
Any help is appreciated. Thanks.
EDIT 2:
Yet to find a good solution. Here are the solutions that I have found that don't quite work:
The above solution: unsyncs far too often
Pinterest List View: no OnScrollListener/onItemClick differentiation
StaggeredGridView: No onScrollListener
Stag Project: No onItemClick listener
Linear Layout Method: No onItemClick Listener
Any ideas? Thanks.
Okay, so I ended up using the Linear Layout Method(See the Question) and used setTag to get the onItemClickListener working, and a CustomScrollView implementation to get the infinite List working.
Basically, two linearLayouts stacked horizontally, inside a scrollview. It works rather well, and loads much faster.
Also, to load my images SmartImageView if that helped.
If someone wants the code, I might be able to post parts of it.
Instead of listening to onTouch why don't you scroll lists in the onScroll listener of ListViews. That's what I'm using in that library with sort of tracks the scroll of a ListView similarly and it works like a charm. Check out this file. https://github.com/JlUgia/list_moving_container/blob/master/src/com/ugia/listmovingcontainer/fragment/BottomListMovingContainerFragment.java
Pay attention specially to 81 (don't forget to add the global layout updater listener) and 89 (with the onScroll Listener).
That way you can forget about the click hacks as well.
UPDATE
I'd code it the following way.
lv1.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
updateListPosition(lv2, lv1);
}
});
lv1.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
updateListPosition(lv2, lv1);
}
});
lv2.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
updateListPosition(lv1, lv2);
}
});
lv2.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
updateListPosition(lv1, lv2);
}
});
private void updateListPosition(ListView updatedList, ListView scrolledList){
updatedList.setScrollY(scrolledList.getScrollY());
}
** setScrollY already invalidates your list.
** Note that I didn't test the code. Although it should be simple enough.
as demonstrated here by jalopaba, I already created a new class: How do you get the selected value of a Spinner?
public class MyItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
String selected = parent.getItemAtPosition(pos).toString();
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
}
and registering this to the spinner in the original class:
spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
However, I still can't use that selected string yet to fill in my code in the same class:
textView.setText(selected);
I'm new to this Android anyway, so this question may be too dummy to some of you
Add the setText code in the onItemSelected:
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
yourTextView.setText(parent.getSelectedItem().toString);
}
Try this code,I hope It's help you.
final CharSequence[] array_min = {"No
Min","100","200","300","400", "500","600","700","800","900","1000",
"1100","1200","1300","1400","1500","1600","1700","1800","1900","2000","2500","3000","3500" };
Spinner s = (Spinner) layout.findViewById(R.id.viewSpin);
adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item, array_min);
s.setAdapter(adapter);
s.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View arg1,
int arg2, long arg3)
{
selItem = parent.getSelectedItem().toString();
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
Use global variable..make following changes in your code
String selected="";
public class MyItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
selected = parent.getItemAtPosition(pos).toString();
}
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
}
textView.setText(selected);
After register spinner ,you can get selected item from getSelectedItem() method on any action such ocClick()
regType = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.regType, android.R.layout.simple_spinner_dropdown_item);
regType.setAdapter(adapter);
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSave:
intent.putExtra("regtype",regType.getSelectedItem().toString());
startActivity(intent);
break;}}