未调用适配器中的 ListFragment 和 getView() [英] ListFragment Not Rendering and getView() in Adapter Not Being Called

查看:37
本文介绍了未调用适配器中的 ListFragment 和 getView()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,这可能是因为我的 ListView 没有显示,我已经验证 getCount 返回的值不是零,但我看不出我做错了什么.

From what I can gather it appears that this might be because my ListView is not being displayed, I've verified that getCount is returning a value not zero, but I can't see what I'm doing wrong.

一切都加载并表现得像在工作,但 ListView 从未出现,我在 mix.xml 中的片段引用上添加了背景色,它在那里并占据全屏,但是当我在 ListView 上设置背景色时它没有出现,就好像它根本没有被渲染.

Everything loads and acts like it's working but the ListView never appears, I put a background color on the fragment reference in mixed.xml and it is there and taking up the full screen, but when I set a background color on my ListView it does not appear, it's like it's not being rendered at all.

更奇怪的是,我的适配器中没有调用 getView,这是我移植到片段的常规活动中的所有工作代码.

More odd, getView is not being called in my adapter, and this is all working code from regular activities that I ported to fragments.

我试过调用notifyDataSetChanged,它没有改变任何东西,调试显示适配器充满了数据,getCount确实返回了一个大于0的准确计数.

I've tried calling notifyDataSetChanged which didn't changed anything, debugging shows the adapter is filled with data and getCount is indeed returning an accurate count greater than 0.

感谢您的帮助,我被卡住了.

Thanks for any help, I'm stuck.

项目是开放的,可以在这里查看 http://code.google.com/p/shack-droid/source/browse/#svn%2FTrunk 但我也在此处包含了相关代码.

Project is open and can be viewed here http://code.google.com/p/shack-droid/source/browse/#svn%2FTrunk but I'm also including the pertinent code here.

这是 ListFragment:

This is the ListFragment:

    public class FragmentTopicView extends ListFragment implements ShackGestureEvent {

        private ArrayList<ShackPost> posts;
        private String storyID = null;

        private String errorText = "";
        private Integer currentPage = 1;
        private Integer storyPages = 1;
        private String loadStoryID = null;
        private Boolean threadLoaded = true;
        private Hashtable<String, String> postCounts = null;
        private AdapterLimerifficTopic tva;

        public FragmentTopicView() {

        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
                // TODO Auto-generated method stub
                super.onCreate(savedInstanceState);

                this.setRetainInstance(true);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

                return inflater.inflate(R.layout.topics, null);
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);

                final ShackGestureListener listener = Helper.setGestureEnabledContentView(R.layout.topics, getActivity());
                if (listener != null) {
                        listener.addListener(this);
                }

                if (savedInstanceState == null) {
                        // get the list of topics
                        GetChattyAsyncTask chatty = new GetChattyAsyncTask(getActivity());
                        chatty.execute();
                }

                ListView lv = getListView();
                lv.setOnScrollListener(new OnScrollListener() {

                        @Override
                        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

                                // start loading the next page
                                if (threadLoaded && firstVisibleItem + visibleItemCount >= totalItemCount && currentPage + 1 <= storyPages) {

                                        // get the list of topics
                                        currentPage++;
                                        GetChattyAsyncTask chatty = new GetChattyAsyncTask(getActivity());
                                        chatty.execute();

                                }
                        }

                        @Override
                        public void onScrollStateChanged(AbsListView view, int scrollState) {

                        }

                });



        }



    class GetChattyAsyncTask extends AsyncTask<String, Void, Void> {
                protected ProgressDialog dialog;
                protected Context c;

                public GetChattyAsyncTask(Context context) {
                        this.c = context;
                }

                @Override
                protected Void doInBackground(String... params) {

                        threadLoaded = false;

                        try {
                                final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
                                final String feedURL = prefs.getString("shackFeedURL", getString(R.string.default_api));
                                final URL url;

                                if (loadStoryID != null) {
                                        if (currentPage > 1)
                                                url = new URL(feedURL + "/" + loadStoryID + "." + currentPage.toString() + ".xml");
                                        else
                                                url = new URL(feedURL + "/" + loadStoryID + ".xml");
                                }
                                else {
                                        if (currentPage > 1)
                                                url = new URL(feedURL + "/" + storyID + "." + currentPage.toString() + ".xml");
                                        else
                                                url = new URL(feedURL + "/index.xml");
                                }

                                // Get a SAXParser from the SAXPArserFactory.
                                final SAXParserFactory spf = SAXParserFactory.newInstance();
                                final SAXParser sp = spf.newSAXParser();

                                // Get the XMLReader of the SAXParser we created.
                                final XMLReader xr = sp.getXMLReader();
                                // Create a new ContentHandler and apply it to the XML-Reader
                                SaxHandlerTopicView saxHandler = new SaxHandlerTopicView(c, "topic");

                                xr.setContentHandler(saxHandler);

                                // Parse the xml-data from our URL.
                                xr.parse(new InputSource(HttpHelper.HttpRequestWithGzip(url.toString(), c)));

                                // Our ExampleHandler now provides the parsed data to us.
                                if (posts == null) {
                                        posts = saxHandler.GetParsedPosts();
                                }
                                else {
                                        ArrayList<ShackPost> newPosts = saxHandler.GetParsedPosts();
                                        newPosts.removeAll(posts);
                                        posts.addAll(posts.size(), newPosts);

                                }

                                storyID = saxHandler.getStoryID();

                                storyPages = saxHandler.getStoryPageCount();

                                if (storyPages == 0) // XML returns a 0 for stories with only
                                                                                // one page
                                        storyPages = 1;

                        }
                        catch (Exception ex) {
                                // TODO: implement error handling

                        }

                        return null;
                }

                @Override
                protected void onPreExecute() {
                        super.onPreExecute();

                        if (currentPage == 1)
                                dialog = ProgressDialog.show(getActivity(), null, "Loading Chatty", true, true);
                        else
                                SetLoaderVisibility(View.VISIBLE);
                }

                @Override
                protected void onPostExecute(Void result) {
                        super.onPostExecute(result);

                        ShowData();

                        SetLoaderVisibility(View.GONE);

                        try {
                                dialog.dismiss();
                        }
                        catch (Exception e) {
                        }

                }

        }



     private void ShowData() {

                if (posts != null) {
                        Hashtable<String, String> tempHash = null;

                        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
                        final String login = prefs.getString("shackLogin", "");
                        final int fontSize = Integer.parseInt(prefs.getString("fontSize", "12"));

                        try {
                                postCounts = GetPostCache();
                        }
                        catch (Exception ex) {

                        }
                        if (postCounts != null)
                                tempHash = new Hashtable<String, String>(postCounts);

                        if (tva == null) {
                                tva = new AdapterLimerifficTopic(getActivity(), R.layout.lime_topic_row, posts, login, fontSize, tempHash);
                                setListAdapter(tva);
                        }
                        else {
                                tva.SetPosts(posts);
                                tva.notifyDataSetChanged();
                        }

                        final ListView lv = getListView();
                        lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
                                @Override
                                public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
                                        menu.setHeaderTitle("Options");
                                        menu.add(0, 1, 0, "Copy Post Url to Clipboard");
                                        menu.add(0, 2, 0, "Watch Thread");
                                        menu.add(0, 3, 0, "Thread Expires In?");
                                        menu.add(0, 4, 0, "Shacker's Chatty Profile");
                                }
                        });

                        // update the reply counts for the listing of topics
                        try {
                                UpdatePostCache();

                        }
                        catch (Exception e) {

                        }

                }
                else {
                        if (errorText.length() > 0) {

                                try {
                                        new AlertDialog.Builder(getActivity()).setTitle("Error").setPositiveButton("OK", null).setMessage(errorText).show();
                                }
                                catch (Exception ex) {
                                        // could not create a alert for the error for one reason
                                        // or another
                                        Log.e("ShackDroid", "Unable to create error alert ActivityTopicView:468");
                                }
                        }
                }
                threadLoaded = true;
        }

}

这是我的 FragmentActivity:

Here's my FragmentActivity:

  public class FragmentActivityTopic extends FragmentActivity {
        @Override
        protected void onCreate(Bundle arg) {
                // TODO Auto-generated method stub
                super.onCreate(arg);

                setContentView(R.layout.mixed);
        }
}

这是我正在使用的适配器,如上所述,没有调用 getView:

This is the Adapter I'm using, and as mentioned above getView is not being called:

public class AdapterLimerifficTopic extends BaseAdapter {

        // private Context context;
        private List<ShackPost> topicList;
        private final int rowResouceID;
        private final String shackLogin;
        private final Typeface face;
        private final int fontSize;
        private final Hashtable<String, String> postCache;
        private final String showAuthor;
        private final Resources r;
        private int totalNewPosts = 0;

        LayoutInflater inflate;// = LayoutInflater.from(context);

        public AdapterLimerifficTopic(Context context, int rowResouceID, List<ShackPost> topicList, String shackLogin, int fontSize, Hashtable<String, String> postCache) {
                this.topicList = topicList;
                this.rowResouceID = rowResouceID;
                this.shackLogin = shackLogin;
                this.fontSize = fontSize;
                this.postCache = postCache;
                this.r = context.getResources();

                face = Typeface.createFromAsset(context.getAssets(), "fonts/arial.ttf");

                final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
                showAuthor = prefs.getString("showAuthor", "count");

                inflate = LayoutInflater.from(context);
        }
        public void SetPosts(List<ShackPost> posts)
        {
                topicList = posts;
        }
        @Override
        public int getCount() {
                return topicList.size();
        }

        @Override
        public Object getItem(int position) {
                return topicList.get(position);
        }

        @Override
        public long getItemId(int position) {
                // return position;
                final ShackPost post = topicList.get(position);
                return Long.parseLong(post.getPostID());
        }

        static class ViewHolder {
                TextView posterName;
                TextView datePosted;
                TextView replyCount;
                TextView newPosts;
                TextView postText;
                TextView viewCat;
                RelativeLayout topicRow;
                ImageView postTimer;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

                // TextView tmp;
                // final View v;
                ViewHolder holder;
                final ShackPost post = topicList.get(position);

                if (convertView == null) {
                        convertView = inflate.inflate(rowResouceID, parent, false);
                        holder = new ViewHolder();
                        holder.posterName = (TextView) convertView.findViewById(R.id.TextViewLimeAuthor);
                        holder.datePosted = (TextView) convertView.findViewById(R.id.TextViewLimePostDate);
                        holder.replyCount = (TextView) convertView.findViewById(R.id.TextViewLimePosts);
                        holder.newPosts = (TextView) convertView.findViewById(R.id.TextViewLimeNewPosts);
                        holder.postText = (TextView) convertView.findViewById(R.id.TextViewLimePostText);
                        holder.viewCat = (TextView) convertView.findViewById(R.id.TextViewLimeModTag);
//                      holder.topicRow = (RelativeLayout) convertView.findViewById(R.id.TopicRow);
//                      holder.postTimer = (ImageView) convertView.findViewById(R.id.ImageViewTopicTimer);

//                      holder.posterName.setTypeface(face);
//                      holder.datePosted.setTypeface(face);
//                      holder.replyCount.setTypeface(face);
//                      holder.newPosts.setTypeface(face);
                        holder.postText.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
//                      holder.postText.setTypeface(face);

                        convertView.setTag(holder);
                }
                else {
                        holder = (ViewHolder) convertView.getTag();
                }

//              holder.postTimer.setImageResource(Helper.GetTimeLeftDrawable(post.getPostDate()));
//
                holder.posterName.setText(post.getPosterName());
//
//              if (shackLogin.equalsIgnoreCase(post.getPosterName()))
//                      holder.posterName.setTextColor(Color.parseColor("#00BFF3"));
//              else
//                      holder.posterName.setTextColor(Color.parseColor("#ffba00"));
//
                holder.datePosted.setText(Helper.FormatShackDateToTimePassed(post.getPostDate()));

                holder.replyCount.setText(post.getReplyCount());
//
//              if (showAuthor.equalsIgnoreCase("count") && post.getIsAuthorInThread())
//                      holder.replyCount.setTextColor(Color.parseColor("#0099CC"));
//              else
//                      holder.replyCount.setTextColor(Color.parseColor("#FFFFFF"));
// clipped code
                holder.postText.setText(preview);


//              if (showAuthor.equalsIgnoreCase("topic") && post.getIsAuthorInThread()) {
//                      final Drawable d = r.getDrawable(R.drawable.background_gradient_blue);
//                      holder.topicRow.setBackgroundDrawable(d);
//              }
//              else
//                      holder.topicRow.setBackgroundDrawable(null);


                // TODO: clean this up a little / also replicated in ShackDroidThread ick
                final String postCat = post.getPostCategory();
                holder.viewCat.setVisibility(View.VISIBLE);

                if (postCat.equals("offtopic"))  {
                        holder.viewCat.setText("offtopic");
                        holder.viewCat.setBackgroundColor(Color.parseColor("#444444"));
                }
                else if (postCat.equals("nws")) {
                        holder.viewCat.setText("nws");
                        holder.viewCat.setBackgroundColor(Color.parseColor("#CC0000"));
                }
                else if (postCat.equals("political")) {
                        holder.viewCat.setText("political");
                        holder.viewCat.setBackgroundColor(Color.parseColor("#FF8800"));
                }
                else if (postCat.equals("stupid")) {
                        holder.viewCat.setText("stupid");
                        holder.viewCat.setBackgroundColor(Color.parseColor("#669900"));
                }
                else if (postCat.equals("informative")) {
                        holder.viewCat.setText("interesting");
                        holder.viewCat.setBackgroundColor(Color.parseColor("#0099CC"));
                }
                else 
                        holder.viewCat.setVisibility(View.GONE);                


                return convertView;
        }

        public int getTotalNewPosts() {
                return totalNewPosts;
        }

}

和相关的 XML:

mixed.xml(这是片段的布局,现在只有一个)

mixed.xml (this is the layout for the fragments, only the one for now)

 <?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="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" 
    android:id="@+id/LinearLayoutMixed">

    <fragment
        android:id="@+id/MixedThreads"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        class="com.stonedonkey.shackdroid.FragmentTopicView"
        >
    </fragment>

</LinearLayout>

Topics.xml(包含 ListView 以及滑动托盘和其他一些东西.

Topics.xml (this contains the ListView as well as a sliding tray and some other stuff.

 <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"  >

            <ListView
                android:id="@android:id/list"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_above="@+id/TopicLoader"
                android:divider="#333333"
                android:dividerHeight="1dip"
                android:textColor="#FFFFFF"

                 />

            <RelativeLayout
                android:id="@+id/TopicLoader"
                android:layout_width="fill_parent"
                android:layout_height="35dip"
                android:layout_alignParentBottom="true"
                android:gravity="center_horizontal"
                android:visibility="gone"
                android:layout_marginTop="5dip" >

                <TextView
                    android:id="@+id/TextViewTopicLoaderText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:focusable="false"
                    android:focusableInTouchMode="false"
                    android:text="Loading" 

                    >
                </TextView>

                <ImageView
                    android:id="@+id/ImageViewTopicLoader"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/TextViewTopicLoaderText"
                    android:src="@drawable/ic_action_refresh"
                    android:layout_alignBottom="@+id/TextViewTopicLoaderText"
                     />
            </RelativeLayout>

            <SlidingDrawer
                android:id="@+id/SlidingDrawer01"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_below="@+id/TopicLoader"
                android:animateOnClick="true"
                android:content="@+id/bookMarkParent"
                android:handle="@+id/TextViewTrayHandle"
                android:orientation="vertical"
                android:paddingTop="200dip"
                android:visibility="gone" >

                <TextView
                    android:id="@+id/TextViewTrayHandle"
                    android:layout_width="fill_parent"
                    android:layout_height="35dip"
                    android:background="@drawable/darkgrey_gradient"
                    android:focusable="false"
                    android:focusableInTouchMode="false"
                    android:gravity="center_vertical" >
                </TextView>

                <RelativeLayout
                    android:id="@id/bookMarkParent"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" >

                    <ListView
                        android:id="@+id/ListViewWatchedThreads"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:divider="#333333"
                        android:dividerHeight="1dip"
                        android:textColor="#FFFFFF" >
                    </ListView>
                </RelativeLayout>
            </SlidingDrawer>

        </RelativeLayout>

最后是lime_topic_row,这是我为上述布局中的 ListView 自定义的行布局:

and finally lime_topic_row which is my custom row layout for the ListView in the above layout:

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="#FF0000" >

        <TextView
            android:id="@+id/TextViewLimeModTag"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FF0000"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dip"
            android:textColor="#000000"
            android:padding="2dip"
            android:textSize="10dip"
            />    
        <TextView
            android:id="@+id/TextViewLimePostText"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:minHeight="20dip"
            android:padding="10dip"
            android:layout_below="@+id/TextViewLimeModTag"
            android:textColor="#FFFFFF" />

        <TextView
            android:id="@+id/TextViewLimeAuthor"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/TextViewLimePostText"
            android:paddingBottom="10dip"
            android:paddingLeft="10dip"
            android:textColor="#0099CC" />

        <TextView
            android:id="@+id/TextViewPosted"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/TextViewLimePostText"
            android:layout_toRightOf="@+id/TextViewLimeAuthor"
            android:paddingBottom="10dip"
            android:text=" posted " />

        <TextView
            android:id="@+id/TextViewLimePostDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/TextViewLimePostText"
            android:layout_toRightOf="@+id/TextViewPosted"
            android:paddingBottom="10dip"
            android:paddingRight="10dip"
            android:textColor="#FF8800" />



        <TextView
            android:id="@+id/TextViewLimePosts"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/TextViewLimePostDate"
            android:layout_marginRight="3dip"
            android:layout_below="@+id/TextViewLimePostText"
            android:layout_marginBottom="15dip"
            android:layout_toLeftOf="@+id/TextViewLimeNewPosts"
            android:background="#BBBBBB"
            android:padding="3dip"
            android:minWidth="25dip"
            android:gravity="center"
            android:textColor="#000000" />

        <TextView
            android:id="@+id/TextViewLimeNewPosts"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/TextViewLimePostDate"
            android:layout_below="@+id/TextViewLimePostText"
            android:layout_marginBottom="15dip"
            android:layout_marginRight="10dip"
            android:background="#669900"
            android:padding="3dip"
            android:minWidth="25dip"
            android:gravity="center"
            android:layout_alignParentRight="true"
            android:textColor="#000000" />

    </RelativeLayout>

推荐答案

我想我发现了问题.出现此问题的原因是您在 FragmentTopicView 中的 onActivityCreated 方法开始时设置的 ShackGestureListener:

I think I found the problem. The issue appears because of the ShackGestureListener that you setup at the start of the onActivityCreated method in the FragmentTopicView:

final ShackGestureListener listener = Helper.setGestureEnabledContentView(R.layout.topics, getActivity());
if (listener != null) {
    listener.addListener(this);
}

setGestureEnabledContentView() 方法中,您检查用户是否在首选项中启用了手势,或者 android 版本是否大于 3.无论哪种方式,truefalse 您为 FragmentActivityTopic 再次 设置内容视图(使用 FragmentTopicView 的布局).不幸的是,再次设置内容视图将覆盖当前布局,该布局包含带有数据的 ListView(ListView 可以毫无问题地填充).当您运行那些 AsyncTasks 以获取数据时,最后将数据设置在正确的 ListView(由 getListView 返回)上,因为 getListView 将持有对在 onCreateView 方法中设置的旧的正确 ListView 的引用,但你看不到任何东西,因为在 >setGestureEnabledContentView 你覆盖了这个 ListView.

In the setGestureEnabledContentView() method you check to see if the user enabled the gestures in the preferences or if the android version is bigger then 3. Either way, true or false you set the content view for the FragmentActivityTopic again(with the layout of the FragmentTopicView). Setting the content view again will, unfortunately, cover the current layout which holds the ListView with data(ListView that populates with no problems). When you run those AsyncTasks to get the data, at the end you set the data on the correct ListView(returned by getListView) because the getListView will hold a reference to the old correct ListView which was set in the onCreateView method, but you don't see anything because in the setGestureEnabledContentView you cover this ListView.

如果您在 HelperHelperAPI4 类中简单注释掉(或删除)为活动设置内容视图的行,则很容易看到这种行为.查看您的 ListView 是否被覆盖的另一种方法是,例如使用 getListView<为 ListView(tva) 设置适配器/code> 并使用 getActivity().findViewById(android.R.id.list)(我已经在选择您的菜单项之一时完成了此操作,因此我可以控制何时更换适配器):

This behavior is easy to see if you simple comment out(or remove) the lines that set the content view for the activity in the Helper and HelperAPI4 classes. Another way to see that your ListView is covered is, for example to set the adapter for the ListView(tva) using getListView and using the getActivity().findViewById(android.R.id.list)(I've done this on selecting one of your menus items, so I can control when I replace the adapter):

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Intent intent;
    switch (item.getItemId())
    {
    case R.id.topic_menu_newpost: // Launch post form
//this doesn't work as the getListView will return a reference to the old ListView
ListView lv = getListView();
lv.setAdapter(tva);
// this will work as you get a reference to the new ListView on top
ListView lv = (ListView) getActivity().findViewById(android.R.id.list);
lv.setAdapter(tva);

我不知道推荐什么作为解决方案,因为我不太明白你在做什么,但我怀疑它是否需要再次为活动设置内容视图(你应该从这里开始工作).

I don't know what to recommend as a solution as I don't quite understand what you're doing, but I doubt that it requires to set the content view for the activity again(and you should work from this).

这篇关于未调用适配器中的 ListFragment 和 getView()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆