Project Practice ①-high imitation zhihu daily (2)-> Use pullrefesh + Slidingmenu + custom components to write the main layout 2, extjs custom components
At the beginning of this article, I would like to thank my teacher, Comrade Li Weimin, for failing to do this thing without him. With his Demo approaching the real XX daily report
It seems that my brain is clearer in the early morning, which helps me clean up my thinking and continue to write my blog. After finishing the previous section, the content of Slidingmenu has been filled, it seems to be a bit fun, that is, the click event of listview.
① Listview click event processing originally thought that the data on the home page is the same as that on other pages, that is, I want to use a Fragment to write all the data in it. It seems impossible. I will not write the Fragment of the main layout because there is a custom class in it. First, it is easy to write data on other pages.
/* -------------------- ListView Click Event ------------------ */@ Overridepublic void onItemClick (AdapterView <?> Parent, View view, int position, long id) {// close the menu. toggle (); if (position = 0) {// enter the home page initView ();} else {// fill in FragmentThemeOther other = theme. getOthers (). get (position); cTitle. setTitle (other. getName (); FragmentTransaction fragmentTransaction = getSupportFragmentManager (). beginTransaction (); fragmentTransaction. replace (R. id. fl_content, ContentFragment. newInstance (other. getId (), other. getDescription (), other. getImage (); fragmentTransaction. commit ();}}
In fact, it's only the Framlayout of the main layout changing. So we can change the title first, and then splice the ID (spliced URL) description (Fragment) to be passed) the title image Fragment. The top image is a little abstract. Look at the layout.
Is it clear at a glance? Like I said, it is mainly because passing values in Fragment should not use constructor bundle. This will make Fragment unable to implement many things, and we need to change the newInstance method.
② Fragment code implementation is not suitable for Fragment at the very beginning, because it always appears together with Viewpage, and then it is relatively simple to appear one by one. When it appears together, I will crash, later, the more convenient it is, the less activity actually used ...................... its lifecycle is very important ...... obtain data from the activity
public static ContentFragment newInstance(long id, String description, String image) {ContentFragment f = new ContentFragment();Bundle args = new Bundle();args.putLong("id", id);args.putString("description", description);args.putString("image", image);f.setArguments(args);return f;}
2. Prepare data in Oncreate
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);id = getArguments().getLong("id");description = getArguments().getString("description");image = getArguments().getString("image");mQueue = Volley.newRequestQueue(getActivity());}
Second, the initialization interface in OncreateView should first fill in a layout. In fact, you can see the source code of the Activity. In fact, setContentView is not much different from the inflate of Fragment.
View view = inflater.inflate(R.layout.fragment_content, container, false);
Let me show you the layout so that the following interface names cannot be understood.
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ScrollView android:id="@+id/sv_content" android:layout_width="match_parent" android:layout_height="match_parent" tools:ignore="UselessLeaf,UselessParent" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="200dp" tools:ignore="UselessLeaf,UselessParent" > <com.android.volley.toolbox.NetworkImageView android:id="@+id/img_content" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" tools:ignore="ContentDescription" /> <TextView android:id="@+id/tx_desc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginTop="10dp" android:padding="10dp" android:textColor="#FFFFFF" android:textSize="18sp" /> </RelativeLayout> <com.qf.teach.project.zhihudaily.custom.CustomListViewForScrollView android:id="@+id/lv_theme" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="#EEEEEE" android:dividerHeight="5dp" android:padding="10dp" /> </LinearLayout> </ScrollView></LinearLayout>
There is a custom listview in it to solve the problem of getting focus from ScrollView.
package com.qf.teach.project.zhihudaily.custom;import android.content.Context;import android.util.AttributeSet;import android.widget.ListView;public class CustomListViewForScrollView extends ListView {public CustomListViewForScrollView(Context context) {super(context);}public CustomListViewForScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public CustomListViewForScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}}
Return to the java code ....................
/** Initialization interface * @ param view */private void initView (View view) {// set the ad page title txDesc = (TextView) view. findViewById (R. id. tx_desc); txDesc. setText (description); // set imgContent = (NetworkImageView) view on the ad page. findViewById (R. id. img_content); imgContent. setImageUrl (image, new ImageLoader (mQueue, new BitmapCache (); adapter = new MyBaseAdapter (); // custom listviewlvTheme = (CustomListViewForScrollView) view. findViewById (R. id. lv_theme); lvTheme. setOnItemClickListener (this); lvTheme. setAdapter (adapter); svContent = (ScrollView) view. findViewById (R. id. sv_content );}
3. initialize data-use volly to obtain json
/*** Initialize data */private void initData () {mQueue. add (new JsonObjectRequest (Method. GET, String. format (API. getTheme (), id), null, this, null ));}
Let's take a look at the json structure. I believe that I will not describe it in json parsing.
In the Stringformat, I have mentioned earlier that the parameter ID is passed in using placeholders to splice strings.
/* -------------------- Network request ------------------ */@ Overridepublic void onResponse (JSONObject response) {try {themeStory = new ThemeStory (); themeStory. setDescription (response. getString ("description"); themeStory. setBackground (response. getString ("background"); themeStory. setImage (response. getString ("image"); themeStory. setColor (response. getInt ("color"); themeStory. setImage_source (response. getString ("Image_source"); themeStory. setName (response. getString ("name"); // parse storiesJSONArray arrayStories = response. getJSONArray ("stories"); if (arrayStories! = Null & arrayStories. length ()> 0) {List <Story> stories = new ArrayList <Story> (); for (int I = 0; I <arrayStories. length (); I ++) {JSONObject obj = arrayStories. getJSONObject (I); Story story = new Story (); story. setType (obj. getInt ("type"); story. setId (obj. getLong ("id"); story. setShare_url (obj. getString ("cmd_url"); story. setTitle (obj. getString ("title"); if (obj. has ("multipic") {story. setMultipic (Obj. getBoolean ("multipic");} // Image array if (obj. has ("images") {JSONArray array = obj. getJSONArray ("images"); if (array! = Null & array. length ()> 0) {String [] images = new String [array. length ()]; for (int x = 0; x <array. length (); x ++) {images [x] = array. getString (x);} story. setImages (images) ;}} stories. add (story);} themeStory. setStories (stories);} // parse editorsJSONArray arrayEditors = response. getJSONArray ("editors"); if (arrayEditors! = Null & arrayEditors. length ()> 0) {List <Editor> editors = new ArrayList <Editor> (); for (int I = 0; I <arrayEditors. length (); I ++) {JSONObject obj = arrayEditors. getJSONObject (I); Editor editor = new Editor (); editor. setAvatar (obj. getString ("avatar"); editor. setId (obj. getLong ("id"); editor. setName (obj. getString ("name"); editors. add (editor);} themeStory. setEditors (editors);} // we notify the data to change the adapter because the URl changes. notifyDataSetChanged (); // solves the problem svContent that is not at the top of the page. smoothScrollTo (0, 0);} catch (JSONException e) {e. printStackTrace ();}}
4. There is nothing to say about filling the data in the adapter. Check the code.
/* -------------------- Network request ------------------ */class MyBaseAdapter extends BaseAdapter {private ViewHolder viewHolder; @ Overridepublic int getCount () {return themeStory = null? 0: themeStory. getStories (). size () ;}@ Overridepublic Object getItem (int position) {return themeStory. getStories (). get (position) ;}@ Overridepublic long getItemId (int position) {return position ;}@ Overridepublic View getView (int position, View convertView, ViewGroup parent) {if (convertView = null) {convertView = LayoutInflater. from (getActivity ()). inflate (R. layout. list_theme_news, parent, false); viewH Older = new ViewHolder (); viewHolder. txTitle = (TextView) convertView. findViewById (R. id. tx_title); viewHolder. imgThumb = (NetworkImageView) convertView. findViewById (R. id. img_thumb); convertView. setTag (viewHolder);} else {viewHolder = (ViewHolder) convertView. getTag ();} Story story = themeStory. getStories (). get (position); viewHolder. txTitle. setText (story. getTitle (); viewHolder. imgThumb. setVisibility (Vie W. GONE); if (story. getImages ()! = Null & story. getImages (). length> 0) {viewHolder. imgThumb. setImageUrl (story. getImages () [0], new ImageLoader (mQueue, new BitmapCache (); viewHolder. imgThumb. setVisibility (View. VISIBLE);} return convertView;} class ViewHolder {public TextView txTitle; public NetworkImageView imgThumb ;}}