why can't I contact the second page
This is inside my Adapter
holder.btn_filter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (position == 1)
{
ShowMessages showMessages = new ShowMessages();
showMessages.message();
}
}}
Home Activity
public class ShowMessages extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_messages);
}
public void message()
{
Toast.makeText(this, "hola", Toast.LENGTH_SHORT).show();
//or set text or change adapter etc...
}
}
When called with message() inside adapter comes out of the application why ?
I see that ShowMessages is an activity here and when you try to instantiate an activity through new, the context is null. Always use intents to create new activities. If you want to trigger some method in the activity from the adapter, pass the activity to the adapter as the constructor argument, cache it in the adapter and then use it to call message().
Something like this would do:
ShowMessages.java - adapter initialization in activity:
MyAdapter adapter = new MyAdapter(this);
MyAdapter.java:
private Activity activity;
MyAdapter(ShowMessages activity) {
this.activity = activity;
}
And then in your adapter:
holder.btn_filter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (position == 1)
{
activity.message();
}
}}
Also, you are being memory efficient here, as you are not instantiating a new activity for every click at position 1.
Related
I have a problem with passing data in android. let me explain my problem.
there are two activities called MainActivity and ProductInformationActivity.
in mainActivity there is a settingButton and onClickListener of the button, a bottom sheet dialog will open up. in bottomSheetDialog there are saveButton and three editText. whenever a user click on saveButton it should pass editTexts data's as PercentageClass to productInformationActivity . (percentage Class is a model to save percentages and pass theme between activities).
I create an interface Called "OnPercentageClicked" then I created an instance of this interface and create setter for that (setOnAddPercentageClicked).
in saveButtonListener I create instance of percentege class and set EditTexts data to it and finally I add percentage to interface's method.
this is mainACtivity:
public class MainActivity extends AppCompatActivity {
private View bottomSheetView;
private BottomSheetDialog bottomSheetDialog;
private OnAddPercentageClicked onAddPercentageClicked;
public void setOnAddPercentageClicked(OnAddPercentageClicked onAddPercentageClicked) {
this.onAddPercentageClicked = onAddPercentageClicked;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar mainToolbar = findViewById(R.id.mainToolbar);
setSupportActionBar(mainToolbar);
ImageButton settingbtn = findViewById(R.id.activityMain_settingBTN);
ViewPager2 viewPager2 = findViewById(R.id.activityMain_viewpager);
TabLayout tabLayout = findViewById(R.id.activityMain_tabLayout);
MainViewPagerAdapter adapter = new MainViewPagerAdapter(this);
viewPager2.setAdapter(adapter);
createDialog();
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
switch (position){
case 0 : tab.setText("کالا ها"); break;
case 1 : tab.setText("دسته بندی ها"); break;
}
}
});
tabLayoutMediator.attach();
settingbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bottomSheetDialog.show();
TextInputEditText firstPercentage = bottomSheetDialog.findViewById(R.id.priceIncrementPercentage_firstPercentageET);
TextInputEditText secondPercentage = bottomSheetDialog.findViewById(R.id.priceIncrementPercentage_secondPercentageET);
TextInputEditText thirdPercentage = bottomSheetDialog.findViewById(R.id.priceIncrementPercentage_thirdPercentageET);
Button percentageSaveButton = bottomSheetDialog.findViewById(R.id.priceIncrementPercentage_saveBTN);
assert percentageSaveButton != null;
percentageSaveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (firstPercentage.getText().length()>0 && secondPercentage.getText().length()>0 && thirdPercentage.getText().length()>0){
Percentage percentage = new Percentage();
percentage.setFirstPercentage(Integer.parseInt(firstPercentage.getText().toString()));
percentage.setSecondPercentage(Integer.parseInt(secondPercentage.getText().toString()));
percentage.setThirdPercentage(Integer.parseInt(thirdPercentage.getText().toString()));
onAddPercentageClicked.onButtonClicked(percentage);
bottomSheetDialog.dismiss();
Toast.makeText(MainActivity.this, "ذخیره شد", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MainActivity.this, "لطفا همه ی فیلد ها را پر کنید", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
public void createDialog(){
bottomSheetDialog = new BottomSheetDialog(MainActivity.this,R.style.bottom_sheet_dialog_theme);
bottomSheetDialog.setContentView(getLayoutInflater().inflate(R.layout.price_increment_percentage,(LinearLayout)findViewById(R.id.priceIncrementPercentage_container),false));
}
}
in productInfomation Activity i want to get the percentage class which i used in MainActivity.
so I implement OnAddPercentageClicked then I create an instance of main activity and call the setter which I created in MainActivity (setOnAddPercentageClicked).
this is productInformationActivity :
public class ProductInformation extends AppCompatActivity implements View.OnClickListener ,OnAddPercentageClicked{
private Percentage percentage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_information);
MainActivity mainActivity = new MainActivity();
mainActivity.setOnAddPercentageClicked(this);
TextView productName = findViewById(R.id.activityProductInformation_productNameTV);
TextView productPrice = findViewById(R.id.activityProductInformation_productPriceTV);
TextView productPriceFirstPercentage = findViewById(R.id.productPriceFirstPercentage);
TextView productPriceSecondPercentage = findViewById(R.id.productPriceSecondPercentage);
TextView productPriceThirdPercentage = findViewById(R.id.productPriceThirdPercentage);
TextView productCategoryName = findViewById(R.id.activityProductInformation_categoryNameTV);
ImageButton close = findViewById(R.id.activity_product_information_closeIB);
close.setOnClickListener(this);
if (percentage !=null){
productPriceFirstPercentage.setText("قیمت کالا +"+percentage.getFirstPercentage()+" درصد");
productPriceSecondPercentage.setText("قیمت کالا +"+percentage.getSecondPercentage()+" درصد");
productPriceThirdPercentage.setText("قیمت کالا +"+percentage.getThirdPercentage()+" درصد");
}
//
// }
if (getIntent().hasExtra("PRODUCT")){
Product product = getIntent().getParcelableExtra("PRODUCT");
productName.setText(product.getTitle());
productPrice.setText(String.valueOf(product.getPrice()));
productCategoryName.setText(String.valueOf(product.getCategoryId()));
}
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.activity_product_information_closeIB){
finish();
}
}
#Override
public void onButtonClicked(Percentage percentage) {
Log.i(TAG, "onButtonClicked: " + percentage);
this.percentage = percentage;
}
}
and when i run this code i get an error which says that the interface in MainActicvity is null.
would you please help me ?
thanks.
I have MainActivity and SpinnerActivity, I want to get selected spinner item value from SpinnerActivity into the MainActivity. I tried to declare String as Static, I also tried with getter but without any success.
in Spinner Activity I also have if statement, how can I get value outside "if statement" and "#Override method" into another class?
MainActivity.class
public class MainActivity extends AppCompatActivity {
SpinnerActivity spinnerActivity = new SpinnerActivity();
Spinner spinnerProvince;
String selectedSpinnerProvince = spinnerActivity.inSpinnerSelectedProvince;
// String selectedSpinnerProvince = SpinnerActivity.inSpinnerSelectedProvince;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinnerProvince = findViewById(R.id.spinnerProvince);
populateSpinnerProvinces();
spinnerProvince.setOnItemSelectedListener(spinnerActivity);
}
public void populateSpinnerProvinces() {
ArrayAdapter<String> provincesAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.province));
provincesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProvince.setAdapter(provincesAdapter);
}
}
SpinnerActivity.class
public class SpinnerActivity implements android.widget.AdapterView.OnItemSelectedListener {
public String inSpinnerSelectedProvince;
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.spinnerProvince) {
inSpinnerSelectedProvince = parent.getItemAtPosition(position).toString();
Toast.makeText(parent.getContext(), parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();
} else {// code here}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
I were about to advice you to use Intent to share data between both activities when i noticed that your "SpinnerActivity" is not really an Activity since it not extends Android Activity class (AppCompactActivity or other classes like this).
Your SpinnerActivity is a Listener. You can use it to implement the action to trigger when an action is performed on your Spinner view. For that you need to do it inside the "#Override" method of onItemSelected.
If you don't like to use the previous methode because of the Override methode you should implement directly the action to trigger at on click events on your spinner view in your MainActivity by doing this:
public class MainActivity extends AppCompatActivity {
SpinnerActivity spinnerActivity = new SpinnerActivity();
Spinner spinnerProvince;
String selectedSpinnerProvince = spinnerActivity.inSpinnerSelectedProvince;
// String selectedSpinnerProvince =
SpinnerActivity.inSpinnerSelectedProvince;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinnerProvince = findViewById(R.id.spinnerProvince);
populateSpinnerProvinces();
//spinnerProvince.setOnItemSelectedListener(spinnerActivity);
spinnerProvince.setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.spinnerProvince) {
inSpinnerSelectedProvince = parent.getItemAtPosition(position).toString();
Toast.makeText(parent.getContext(), parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();
} else {// code here}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
public void populateSpinnerProvinces() {
ArrayAdapter<String> provincesAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item,
getResources().getStringArray(R.array.province));
provincesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProvince.setAdapter(provincesAdapter);
}
}
I need to call an Intent from the onBindViewHolder of the recycler adapter , on a click event from one of the views in the ViewHolder. I am unable to do so directly ..
public void onBindViewHolder(MyAdapter.MyViewHolder viewHolder, int i) {
viewHolder.button.setonClickListener(new View.onClickListener(
#Override
onClick(View v) {
Intent i=new Intent();
i.setAction("Intent.ACTION_CALL");
i.setData(Uri.parse("tel:1234567890"));
startActivity(i);
}
));
}
This did not work. It kept throwing error. I then created a public method in the Activity with the same code. Passed Activity context in the Adapter constructor. Then called the Method as follows from button click event.
((MyActivity)context).makePhoneCall("1234567890");
This did the trick. But i feel there should be a better method of doing this.
As i am primarily from C background, i am not sure.
So my question is there a better or more proper way to do this , according to Java programming conventions.
If you need to call another activity via Intent, you can use any view's Context:
v.getContext().startActivity(i);
I think this is a correct method.
Another way is to implement a listener in the recycleradapter and listen it in the activity.
So in the adapter:
public class RecyclerAdapter .... {
private MyClickListener listener;
public void onBindViewHolder(MyAdapter.MyViewHolder viewHolder, int i) {
viewHolder.button.setonClickListener(new View.onClickListener(
#Override
onClick(View v) {
listener.onClicked(true);
}
));
public void setMyClickListener(MyClickListener listener) {
this.listener = listener;
}
}
//create MyClickListener.class
public interface MyClickListener {
public void onClicked(boolean status);
}
In your Activity:
public class MainActivity ... implements MyClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
adapter.setMyClickListener(this);
}
#Override
onClick(boolean status) {
if (status){
Intent i=new Intent();
i.setAction("Intent.ACTION_CALL");
i.setData(Uri.parse("tel:1234567890"));
startActivity(i);
};
}
}
Try this
In your Adapter:
Activity mContext;
public FollowersAdapter(Activity mContext) {
this.mContext = mContext;
}
//And then your click in onBindViewHolder
holder.linear_user.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("linear click>>>>>>>>>>>>");
Intent ToImage = new Intent(mContext, UserData.class);
ToImage.putExtra("user_id", data.get(position).getFollower_id());
mContext.startActivity(ToImage);
}
});
I have 3 Fragments inside a ViewPager. I have different back button functionalities which I want to implement for each Fragment. At the moment, I have created methods in each fragment which correspond to what I want the back button to do. I implemented an interface in my activity with the following methiod:
#Override
public void onCameraBack(int i) {
currFrag = i;
}
The idea here is that there are three fragments, each fragment calls this method in its onStart() method. Fragment 0 passes 0, fragment 1 passes 1 and fragment 2 passes 2. So in this way the holding activity knows which fragment is visible. Now I am trying to get a reference to that fragment to be able to call the backbutton method I have implemented in it. I tried using this :
#Override
public void onBackPressed() {
if (currFrag == 0) {
}
else if (currFrag == 1) {
FragmentBTesting fragmentBTesting= new FragmentBTesting();
fragmentBTesting.FragmentBBack();
}
}`
but this doesn't work. I can't use the findFragmentbyId method since my fragments do not have fragment tags in their XML, they fill the whole screen and their views are defined using linearLayouts. My question is how can I get an instance of the fragment so I can call its FragmentBack() method.
Here is my full activity
public class FragmentActivityTesting extends FragmentActivity implements FragmentATesting.logoutListener,FragmentBTesting.onCameraBack {
ViewPager viewPager = null;
SessionManager session = new SessionManager(MyApp.getContext());
int currFrag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_activity_testing);
viewPager = (ViewPager) findViewById(R.id.pic_pager);
setStatusBarColor();
FragmentManager fragmentManager = getSupportFragmentManager();
viewPager.setAdapter(new MyAdapter(fragmentManager));
viewPager.setCurrentItem(1);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("CLOSE_ALL");
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
#TargetApi(21)
public void setStatusBarColor() {
Window window = this.getWindow();
// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
if (Integer.valueOf(android.os.Build.VERSION.SDK) >= 21) {
window.setStatusBarColor(this.getResources().getColor(R.color.green));
}
}
#Override
public void logout() {
session.logOut();
Intent a = new Intent(this,MainActivity.class);
startActivity(a);
Intent intent = new Intent("CLOSE_ALL");
this.sendBroadcast(intent);
finish();
}
#Override
public void onBackPressed() {
if (currFrag == 0) {
}
else if (currFrag == 1) {
FragmentBTesting fragmentBTesting= new FragmentBTesting();
fragmentBTesting.FragmentBBack();
}
}
#Override
public void onCameraBack(int i) {
currFrag = i;
}
}
class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position ==0) {
fragment = new FragmentATesting();
}
else if (position == 1) {
fragment = new FragmentBTesting();
}
else if (position == 2) {
fragment = new FragmentCTesting();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
}
Instead of telling your activity what fragment you are currently on, why not tell it what to execute when back is pressed?
In your activity you can have a field to hold the callback field (as a Runnable, I know so much hate. You can make your own interface if you want), the setter, and then the onBackPressed implementation. Here is a snippet from my code that works. Im using Guava's Optional class, but you can null it instead if you're into that kinda thing.
This is the Activity which should implement ActivityWithHomeButton
private Optional<? extends Runnable> backButtonListener = Optional.absent();
#Override
public void onBackPressed() {
// Check if there is a custom back button
if (backButtonListener.isPresent()) {
backButtonListener.get().run();
backButtonListener = Optional.absent();
} else {
super.onBackPressed();
}
}
#Override
public void setBackButtonListener(Optional<? extends Runnable> backButtonListener) {
this.backButtonListener = backButtonListener;
}
Here is the interface I implement in the activity
public interface ActivityWithHomeButton {
void setBackButtonListener(Optional<? extends Runnable> runnable);
}
and of course the usage from a fragment
parent.setBackButtonListener(Optional.of(new Runnable() {
#Override
public void run() {
// do back button stuff
}
}));
You can put this wherever you want in the fragment. You are also going to want to clear the back button listener whenever you no longer need it (onPause). You can do this as such
parent.setBackButtonListener(Optional.<Runnable>absent());
Where parent can be attained using the standard activity-fragment communication pattern detailed here (http://developer.android.com/training/basics/fragments/communicating.html). This code goes in your fragment
private ActivityWithHomeButton parent;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
parent = (ActivityWithHomeButton) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement ActivityWithHomeButton");
}
}
Hope it helps!
I am new to Android dev. The way I have been handling clicks has been by setting the android:onClick attribute in the manifest file for buttons. What I am wondering is the best way to handle long clicks in general. I have read about implementing onLongClick(), but is there a way to use handlers (like above), rather than having to extend View? It would be very helpful, as I would rather not have to rebuild my entire project with an extended View class.
EDIT
I should clarify. I have a ListView and I want to set what will happen when I long click on an element in the list. Each element in the list is a TextView. As per one of the answers, I have added the below code, and now I get a force close:
public class TwitterActivity extends ListActivity {
List<String> tweets = new LinkedList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.layout, tweets));
TextView view = (TextView) findViewById(R.id.ListTemplate);
view.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast toast = new Toast(TwitterActivity.this);
toast.setText("LongClick");
toast.show();
return true;
}
});
//...
}
}
For a ListActivity if you want to respond to long clicks on the list elements do this:
public class TwitterActivity extends ListActivity {
List<String> tweets = new LinkedList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this, R.layout.layout, tweets));
ListView lv = getListView();
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id)
{
Toast.makeText(TwitterActivity.this, "LongClick", Toast.LENGTH_LONG).show();
}
});
}
}
For a regular activity you could do something like this:
public class MyActivity extends Activity implements View.onLongClickListener {
View myView = null;
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.my_activity);
myView = findViewById(r.id.my_view);
myView.setOnLongClickListener(this);
}
#Override
public void onLongClick(View v) {
//long clicked
}
}
get a handle to the button using findViewByID, then call setOnLongClickListener.
Button b = (Button)findViewByID (R.id.button1);
b.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//to do
}
});
Sure this is fairly simple:
ImageButton i = (ImageButton) findViewById(R.id.myButton);
i.setOnLongClickListener(new myLongListener());
private class myLongListener implements View.OnLongClickListener {
#Override
public void onClick(View v) {
//your code here
}
}
hope this helps!
You don't have to extend the View class in most cases. View has a method called setOnLongClickListener which you can use directly as all derived classes like Button or TextView, etc. will also have.
The only event handler that has an XML attribute is android:onClick. All other event handlers are registered at runtime from Java code. Technically, even android:onClick is registered at runtime from Java code, but you do not have to write the Java code in question.
So you need to do something like this:
View.OnLongClickListenerhandler = View.OnLongClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.myButton: // doStuff
break;
case R.id.myOtherButton: // doStuff
break;
}
}
}
findViewById(R.id.myButton).setOnLongClickListener(handler);
findViewById(R.id.myOtherButton).setOnLongClickListener(handler);