I am trying to use RadioGroup as a CircularPageIndicator. The problem is with the RadioGroup.OnCheckedChangeListener. It seems to call it self when onPageSelected is called. However I want it to work vice versa i.e. when I select a radioButton it should change a view based on the location of the Array index being provided. However it seems as if onCheckedChange is never called when I change a check on the radio button and so onCheckedChange never triggers.
public class MainActivity extends Activity implements RadioGroup.OnCheckedChangeListener, OnPageChangeListener {
ViewPager mImagePager;
ImagePagerAdapter mPagerAdapter;
RadioGroup mPageIndicator;
boolean swipeChange = false;
int[] mRadioButtonIds = new int[] { R.id.radio0, R.id.radio1, R.id.radio2, R.id.radio3, R.id.radio4 };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initComponents();
mPageIndicator.setOnCheckedChangeListener(this);
mImagePager.setAdapter(mPagerAdapter);
mImagePager.setOnPageChangeListener(this);
}
/**
*
*/
private void initComponents() {
mPageIndicator = (RadioGroup) findViewById(R.id.radioGroup1);
mImagePager = (ViewPager) findViewById(R.id.imgPager);
mPagerAdapter = new ImagePagerAdapter();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int pSelectedPagePosition) {
swipeChange = true;
mPageIndicator.check(mRadioButtonIds[pSelectedPagePosition]);
}
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (!swipeChange) {
int itemPosition = Arrays.asList(mRadioButtonIds).indexOf(checkedId);
mImagePager.setCurrentItem(itemPosition, true);
swipeChange = false;
}
}
}
Note : I don't want to use any third party code/lib to create a custom Circular Page Indicator.
Can any one please point a mistake here. Is there a reason for the RadioGroup not to work?
I forgot to take a look at the documentation!
http://developer.android.com/guide/topics/ui/controls/radiobutton.html
Related
I have an activity with pager adapter which contains some fragments. I've also created a progressBar (horizontal) on the top of the activity. I need that the bar would show the progress when I am swiping through the fragments. For example, it should be grey when I am in the first fragment then gradually grow when I swipe through the fragments and fully green when I am in the last fragment.
mainActivity.java
public class testActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager_adapter);
initialisePaging();
}
private void initialisePaging() {
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this,fragment1.class.getName()));
fragments.add(Fragment.instantiate(this,fragment2.class.getName()));
fragments.add(Fragment.instantiate(this,fragment3.class.getName()));
PagerAdapter mPagerAdapter = new PagerAdapter(this.getSupportFragmentManager(), fragments);
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setAdapter(mPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_test, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
PagerAdapter.java
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int arg0) {
return this.fragments.get(arg0);
}
#Override
public int getCount() {
return this.fragments.size();
}
public void setFragments(List<Fragment> fragments) {
this.fragments = fragments;
}
}
Actually I've found a very simple answer. This is what I did:
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int pos) {
//This is because progress is 0 at the start of the program
progress++;
ProgressBar progress = (ProgressBar) findViewById(R.id.progressBar);
progress.setProgress(position++);
}
});
You need to add OnPageChangeListener to you ViewPager in your Activity like this
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrollStateChanged(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageSelected(int pos) {
// Update the progress bar according to pos
// Also note that you reach the end when pos == mPagerAdapter.getCount() - 1
// and that pos starts at 0 - this is the first fragment
}
});
I'm new to android, started it about a month ago, and now I'm trying to make a "Shopping List" app for the sake of practice. In this app I have a ListView, where user can insert items via EditText above that ListView. When user longClick on item, ContextMenu with "Edit", "Delete" and "Mark" fields appears. I have already made "Delete" button work, but I still have problems with "Edit" function. To make this function work I created DialogFragment class, so when user presses the "Edit" button, this DialogFragment appears. This DF has EditText field, where we enter data we want to change. Here is DialogFragment class code:
public class AlertEdit extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder bd = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
bd.setView(inflater.inflate(R.layout.alert, null))
.setTitle("Edit")
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((MyActivity)getActivity()).doPositiveClick();
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((MyActivity)getActivity()).doNegativeClick();
}
});
return bd.create();
}
as you can see, we have positive button here, which calls doPositiveClick method from MyActivity, which appears to be the main activity.
.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
((MyActivity)getActivity()).doPositiveClick();
}
So, here is the MyActivity class code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
lw = (ListView) findViewById(R.id.listView);
edtxt = (EditText) findViewById(R.id.editText);
alertEd = (EditText) findViewById(R.id.alertEdit);
goods = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, goods);
lw.setAdapter(adapter);
lw.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View v,
int position, long id) {
}
});
registerForContextMenu(lw);
edtxt.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction()== KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
goods.add(0, edtxt.getText().toString());
adapter.notifyDataSetChanged();
edtxt.setText("");
return true;
}
}
return false;
}
});
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo info){
super.onCreateContextMenu(menu, v, info);
getMenuInflater().inflate(R.menu.actions, menu);
}
public boolean onContextItemSelected(MenuItem item) {
position = (int) info.id;
switch (item.getItemId()) {
case R.id.cnt_mnu_delete:
goods.remove(position);
adapter.notifyDataSetChanged();
return true;
case R.id.cnt_mnu_edit:
}
return super.onContextItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void doPositiveClick()
{
}
public void doNegativeClick()
{
}
public void showDialog()
{
DialogFragment frag = new AlertEdit();
frag.show(getFragmentManager(), "edit");
}
}
My problem is that I have no idea how to create that Edit function. I tryied to use AdapterContextMenuInfo, but it works only in onContextItemSelected method, because it requires and Item to work with. Hope you help me and sorry for the possible lack of information, ask me any additional questions please.
P.S. I'm trying to make this dialog for almost two weeks already and I'm really frustrated because of that.
I'm using this method - it's simple and you may adapt it to your needs:
First of all make an interface to handle your result, for example:
public interface OnDialogResultListener {
public void onDialogResult(String result);
}
Then use your dialog with additional view, like this:
public void showDialogAndGetResult(final int title, final String message, final String initialText, final OnDialogResultListener listener) {
// additional View - use appropriate View to your needs:
final EditText editText = new EditText(this);
editText.setText(initialText);
new AlertDialog.Builder(MainActivity.this)//
.setTitle(title)//
.setMessage(message)//
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (listener != null) {
listener.onDialogResult(editText.getText().toString());
}
}
})//
.setNegativeButton(android.R.string.cancel, null)//
.setView(editText)//
.show();
}
At last implement this interface in your activity:
public class YourActivity Extends Activity implements OnDialogResultListener{
...
#Override
public void onDialogResult(String result) {
//do what you need
}
...
}
Edit:
You may replace EditText by any View, including Layouts.
Still you may use the same scheme to return result from your DialogFragment descendant - just pass OnDialogResultListener in constructor or initializing method. I would say AlertDialog is more lightweight and DialogFragment allows more control and you may use both according to your needs.
New programmer here. I want the Add button on my screen to enable only when all fields are non-empty. However, adding a TextWatcher is making the screen crash. Asking elsewhere, it seems I shouldn't try to access my EditText with my ContentView set to activity_add_grade. But I need help understanding the right way to do things.
The template/tutorial I followed had me create 2 xml files per activity. As seen below, my AddClass sets the contentView to activity_add_grade and then inflates fragment_add_grade, which is where my screen design and views are. So the problem with accessing my EditText views from onCreate is that my ContentView is not set to the xml that contains the views. So where should I set my listeners instead? And why are there two xmls anyway? I'd like to understand more and follow the best practice. Thanks!
AddClass -- the java for the activity in question
public class AddClass extends ActionBarActivity {
DBAdapter db = new DBAdapter(this);
private EditText editText1;
private EditText editText2;
public TextWatcher watcher = new TextWatcher(){
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
checkFieldsForEmptyValues();
}
#Override
public void afterTextChanged(Editable editable) {
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_grade);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
// setContentView(R.layout.fragment_add_grade); //Tried this. Doesn't work
editText1 = (EditText)findViewById(R.id.editTitle);
editText2 = (EditText)findViewById(R.id.editCredit);
editText1.addTextChangedListener(watcher);
editText2.addTextChangedListener(watcher);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.add_grade, menu);
//Code here for spinners on screen. Removed for space
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void checkFieldsForEmptyValues() {
Button b = (Button)findViewById(R.id.addClassButton);
System.out.println("in the check fields thing");
String s1 = editText1.getText().toString();
String s2 = editText2.getText().toString();
if(s1.isEmpty() || s2.isEmpty()) {
b.setEnabled(false);
} else {
b.setEnabled(true);
}
}
// THIS WORKS -- the method is bigger, but I shortened it for space.
public void createNewClass(View v) {
EditText titleTxt = (EditText)findViewById(R.id.editTitle);
//ToStrings
String titleStr = titleTxt.getText().toString();
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_add_grade,
container, false);
return rootView;
}
}
Well the view you are looking for is in your fragment's layout, so you should handle that view inside your fragment.
Option A:
remove all EditText-related code from your Activity onCreate method. Create fields watcher and editText1, editText2 inside the Fragment. So your PlaceholderFragment code should look more or less like this:
public static class PlaceholderFragment extends Fragment {
EditText editText1, editText2;
public TextWatcher watcher = new TextWatcher(){
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
checkFieldsForEmptyValues();
}
#Override
public void afterTextChanged(Editable editable) {
}
};
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
editText1 = (EditText) rootView.findViewById(R.id.editTitle);
editText1.addTextChangedListener(watcher);
editText2 = (EditText) rootView.findViewById(R.id.editCredit);
editText2.addTextChangedListener(watcher);
return rootView;
}
}
Option B:
Since it looks like your fragment is the autogenerated one from eclipse and you may not want to use fragments in your code you can do this:
Drop your fragment code & layout and move the edittexts from your fragment layout in to your activitiy layout. Then your onCreate code of the Activity should work.
When I swipe between questions, it loads current page number correctly
BUT when I use next button, first click doesnt loads pagenumber ( I mean onPageSelected() doesnt work.) second and other clicks loads content but it loads 1 page previous.
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main);
mPager = (ViewPager)findViewById(R.id.pager);
QuestionPagerAdapter mAdapter = new QuestionPagerAdapter();
mPager.setAdapter(mAdapter);
OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
#Override
public void onPageScrollStateChanged(int arg0) { }
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) { }
#Override
public void onPageSelected(int position) {
tv.setText( mPager.getCurrentItem()+"");
}
};
mPager.setOnPageChangeListener(pageChangeListener);
Question.next.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
mPager.setCurrentItem(getItem(+1));
}
}
private int getItem(int i) {
int a = mPager.getCurrentItem();
i += a;
return i;
}
});
Why not just doing this in your listener:
mPager.setCurrentItem(mPager.getCurrentItem() + 1);
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);