how to extend a plain java class android? -
i having problems setting complex listview: trying create two-level listview swipe tab layout, second level not react actions taking place (e.g. clicking on item in list).
perhaps need extend plain java file class unsure how this. suggestions?
file mainactivity.java
package com.learn2crack.tab; import android.app.actionbar; import android.app.fragmenttransaction; import android.os.bundle; import android.support.v4.app.fragmentactivity; import android.support.v4.view.viewpager; public class mainactivity extends fragmentactivity implements anitemclicklistener, headlinesfragment.onheadlineselectedlistener { viewpager tab; tabpageradapter tabadapter; actionbar actionbar; public void clickhappens(int position){ //whatever need in response click knowing position in //data set correlated row clicked. // user selected headline of article headlinesfragment // capture article fragment activity layout articlefragment articlefrag = (articlefragment) getsupportfragmentmanager().findfragmentbyid(r.id.article_fragment); if (articlefrag != null) { // if article frag available, we're in two-pane layout... // call method in articlefragment update content articlefrag.updatearticleview(position); } else { // if frag not available, we're in one-pane layout , must swap frags... // create fragment , give argument selected article articlefragment newfragment = new articlefragment(); bundle args = new bundle(); args.putint(articlefragment.arg_position, position); newfragment.setarguments(args); android.support.v4.app.fragmenttransaction transaction = getsupportfragmentmanager().begintransaction(); // replace whatever in fragment_container view fragment, // , add transaction stack user can navigate transaction.replace(r.id.fragment_container, newfragment); transaction.addtobackstack(null); // commit transaction transaction.commit(); } } @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); tabadapter = new tabpageradapter(getsupportfragmentmanager()); tab = (viewpager)findviewbyid(r.id.pager); tab.setonpagechangelistener( new viewpager.simpleonpagechangelistener() { @override public void onpageselected(int position) { actionbar = getactionbar(); actionbar.setselectednavigationitem(position); } }); tab.setadapter(tabadapter); actionbar = getactionbar(); //enable tabs on action bar actionbar.setnavigationmode(actionbar.navigation_mode_tabs); actionbar.tablistener tablistener = new actionbar.tablistener(){ @override public void ontabreselected(android.app.actionbar.tab tab, fragmenttransaction ft) { // todo auto-generated method stub } @override public void ontabselected(actionbar.tab tab, fragmenttransaction ft) { tab.setcurrentitem(tab.getposition()); } @override public void ontabunselected(android.app.actionbar.tab tab, fragmenttransaction ft) { // todo auto-generated method stub }}; //add new tab actionbar.addtab(actionbar.newtab().settext("software search").settablistener(tablistener)); actionbar.addtab(actionbar.newtab().settext("maps").settablistener(tablistener)); actionbar.addtab(actionbar.newtab().settext("scanner").settablistener(tablistener)); } @override public void onarticleselected(int position) { // todo auto-generated method stub } }
file softwaresearchactivity.java
package com.learn2crack.tab; import android.os.bundle; import android.support.v4.app.fragmentactivity; import android.support.v4.app.fragmenttransaction; interface onheadlineselectedlistener { /** called headlinesfragment when list item selected */ public void onarticleselected(int position); } public class softwaresearchactivity extends fragmentactivity implements headlinesfragment.onheadlineselectedlistener { /** called when activity first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.news_articles); // check whether activity using layout version // fragment_container framelayout. if so, must add first fragment if (findviewbyid(r.id.fragment_container) != null) { // however, if we're being restored previous state, // don't need , should return or else // end overlapping fragments. if (savedinstancestate != null) { return; } // create instance of examplefragment headlinesfragment firstfragment = new headlinesfragment(); // in case activity started special instructions intent, // pass intent's extras fragment arguments firstfragment.setarguments(getintent().getextras()); // add fragment 'fragment_container' framelayout getsupportfragmentmanager().begintransaction() .add(r.id.fragment_container, firstfragment).commit(); } } public void onarticleselected(int position) { // user selected headline of article headlinesfragment // capture article fragment activity layout articlefragment articlefrag = (articlefragment) getsupportfragmentmanager().findfragmentbyid(r.id.article_fragment); if (articlefrag != null) { // if article frag available, we're in two-pane layout... // call method in articlefragment update content articlefrag.updatearticleview(position); } else { // if frag not available, we're in one-pane layout , must swap frags... // create fragment , give argument selected article articlefragment newfragment = new articlefragment(); bundle args = new bundle(); args.putint(articlefragment.arg_position, position); newfragment.setarguments(args); fragmenttransaction transaction = getsupportfragmentmanager().begintransaction(); // replace whatever in fragment_container view fragment, // , add transaction stack user can navigate transaction.replace(r.id.fragment_container, newfragment); transaction.addtobackstack(null); // commit transaction transaction.commit(); } } }
file headlinesfragment.java
package com.learn2crack.tab; import android.app.activity; import android.os.build; import android.os.bundle; import android.support.v4.app.listfragment; import android.view.view; import android.widget.arrayadapter; import android.widget.listview; public class headlinesfragment extends listfragment { onheadlineselectedlistener mcallback; // container activity must implement interface frag can deliver messages public interface onheadlineselectedlistener { /** called headlinesfragment when list item selected */ public void onarticleselected(int position); } @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // need use different list item layout devices older honeycomb int layout = build.version.sdk_int >= build.version_codes.honeycomb ? android.r.layout.simple_list_item_activated_1 : android.r.layout.simple_list_item_1; // create array adapter list view, using ipsum headlines array setlistadapter(new arrayadapter<string>(getactivity(), layout, ipsum.headlines)); } @override public void onstart() { super.onstart(); // when in two-pane layout, set listview highlight selected list item // (we during onstart because @ point listview available.) if (getfragmentmanager().findfragmentbyid(r.id.article_fragment) != null) { getlistview().setchoicemode(listview.choice_mode_single); } } @override public void onattach(activity activity) { super.onattach(activity); // makes sure container activity has implemented // callback interface. if not, throws exception. try { mcallback = (onheadlineselectedlistener) activity; } catch (classcastexception e) { throw new classcastexception(activity.tostring() + " must implement onheadlineselectedlistener"); } } @override public void onlistitemclick(listview l, view v, int position, long id) { // notify parent activity of selected item mcallback.onarticleselected(position); // set item checked highlighted when in two-pane layout getlistview().setitemchecked(position, true); } }
file articlefragment.java
package com.learn2crack.tab; import android.os.bundle; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.textview; public class articlefragment extends fragment { final static string arg_position = "position"; int mcurrentposition = -1; @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { // if activity recreated (such screen rotate), restore // previous article selection set onsaveinstancestate(). // necessary when in two-pane layout. if (savedinstancestate != null) { mcurrentposition = savedinstancestate.getint(arg_position); } // inflate layout fragment return inflater.inflate(r.layout.article_view, container, false); } @override public void onstart() { super.onstart(); // during startup, check if there arguments passed fragment. // onstart place because layout has been // applied fragment @ point can safely call method // below sets article text. bundle args = getarguments(); if (args != null) { // set article based on argument passed in updatearticleview(args.getint(arg_position)); } else if (mcurrentposition != -1) { // set article based on saved instance state defined during oncreateview updatearticleview(mcurrentposition); } } public void updatearticleview(int position) { textview article = (textview) getactivity().findviewbyid(r.id.article); article.settext(ipsum.articles[position]); mcurrentposition = position; } @override public void onsaveinstancestate(bundle outstate) { super.onsaveinstancestate(outstate); // save current article selection in case need recreate fragment outstate.putint(arg_position, mcurrentposition); } }
file anitemclicklistener.java
package com.learn2crack.tab; public interface anitemclicklistener { void clickhappens(int i); }
short answer: don't, classes classes b/c said 'class' @ beginning of class; outer classes if outer , match file name
if want communicate between fragment , activity holding it, first write interface; u can away not writing one, it's form , helps organize code:
package com.yourcompany.appname.interfaces; public interface anitemclicklistener { void clickhappens(int i); }
note lack of method body, note since i'm calling interface, don't need specify these abstract, are. can add more methods, , class implements must have clickhappens method or abstract, containing classes do.
then edit top of mainactivity say: 'public class mainactivity extends fragmentactivity implements anitemclicklistener, headlinesfragment.onheadlineselectedlistener {', meaning has methods provide body abstract methods in both anitemclicklistener , headlinesfragment.onheadlineselectedlistener interfaces. @ point ide should throwing error , telling you need implement abstract function, put following method in class:
public void clickhappens(int position){ //whatever need in response click knowing position in //data set correlated row clicked. }
isn't neat-o?
now, can call function in 1 of 2 ways come immediatly mind: if know fragment ever going running part of activity( not being reused, defeats 1 of purposes fragments ) in our fragment can say
mainactivity.this.clickhappens(pos); //where pos position
but isn't using interface.
more robustly, since pass fragment during onattach, make sure callback can cast correctly in onattach so:
class afragment extends listfragment{ activity callback; @override onattach{ try { callback = (anitemclicklistener) activity; //look familiar? } catch (classcastexception e) { throw new classcastexception(activity.tostring() + " must implement anitemclicklistener"); } } }
so when override onlistitemclick,
callback.clickhappens( position );
and you've sent clicked position activity passed 'this' fragment.
tell me if part of isn't clear =]
a more "normal" use of interfaces when like
map map = new hashmap<string, string>;
and then
map.get(s);
in case, though map map, aren't calling .get() of map--map base class--you calling method .get of hashmap.
gl hf
Comments
Post a Comment