【问题标题】:User input from EditText (from GridView) in fragment is not persisting片段中来自 EditText(来自 GridView)的用户输入不持久
【发布时间】:2015-02-08 04:20:43
【问题描述】:

我在GridView 中有一个默认文本和图像,当用户单击EditText 时,他们应该能够更改值并通过SharedPreferences 保存它,所以即使应用程序被杀死,EditText 将保留更改。

但是,这不起作用。当我终止应用程序并返回时,EditText 再次显示默认值。我的猜测是因为我如何使用LayoutInflater,虽然我不确定,因为LayoutInflater Android 文档不是很明确。我在GridView 适配器中使用了一次充气机,在Fragment 布局中使用一次,然后在Fragment 中再次使用以获取EditText,以便用户可以更改它。我是否应该只使用 2 个充气机(比如使用适配器充气机两次,但是如何使用?)我认为我的 SharedPreferences 信息是正确的,但我可能是错的。有什么建议么?谢谢。

CuteCollectionFragment.java

package org.azurespot.cutecollection;

import android.app.Fragment;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;

import org.azurespot.R;

/**
 * Created by mizu on 1/26/15.
 */
public class CuteCollectionFragment extends Fragment {

    GridView gridView;
    GridViewAdapter gridViewAdapter;
    String newTitle;
    EditText mediaTitle;
    ImageView mediaItem;

    protected static final String MEDIA_TITLE = "Media Title";


    public CuteCollectionFragment(){}

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

        View rootView = inflater.inflate(R.layout.fragment_cute_collection,
                                                            container, false);

        // with fragments, make sure you include the rootView when finding id
        gridView=(GridView)rootView.findViewById(R.id.gridView);
        // Create the Custom Adapter Object
        gridViewAdapter = new GridViewAdapter(getActivity());
        // Set the Adapter to GridView
        gridView.setAdapter(gridViewAdapter);

        // get default the Title and Image variables for use
        LayoutInflater inflater2 = LayoutInflater.from(GridViewAdapter.context);
        View gridRow = inflater2.inflate(R.layout.grid_row, null);
        mediaTitle = (EditText) gridRow.findViewById(R.id.media_title);
        mediaItem = (ImageView) gridRow.findViewById(R.id.media_item);

        // Load prefs from previous saves
        loadTitlePreferences();

        // Handling touch/click Event on GridView Item
        gridView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {

            // Code to show photo in dialog box
            }
        });

        return rootView;
    }

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

        // When "Done" enter key pressed on soft keyboard, Title prefs are saved
        mediaTitle.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    switch (keyCode) {
                        case KeyEvent.KEYCODE_DPAD_CENTER:
                        case KeyEvent.KEYCODE_ENTER:
                            saveTitlePreferences();
                            return true;
                        default:
                            break;
                    }
                }

                return false;
            }

        });
    }

    private void loadTitlePreferences() {

        SharedPreferences sp = getActivity().getSharedPreferences(MEDIA_TITLE, 0);
        String name = sp.getString("Media Title", newTitle);

        mediaTitle.setText(name);
    }

    private void saveTitlePreferences(){

        newTitle = mediaTitle.getText().toString();
        // since using a fragment, must put getActivity() before method
        SharedPreferences sp = getActivity()
                .getSharedPreferences(MEDIA_TITLE, 0);

        SharedPreferences.Editor editor = sp.edit();
        editor.putString("Media Title", newTitle);
        // apply() saves in the background, whereas commit();
        // saves immediately
        editor.commit();
    }

}

GridViewAdapter.java

package org.azurespot.cutecollection;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;

import org.azurespot.R;

/**
 * Created by mizu on 2/5/15.
 */
public class GridViewAdapter extends ArrayAdapter {

    public static Context context;
    private EditText mediaTitle;
    private ImageView mediaItem;


    public GridViewAdapter(Context context) {
        super(context, 0);
        this.context = context;

    }

    public int getCount() {
        return 24;
    }

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

        View row = convertView;

        if (row == null)
        {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(R.layout.grid_row, parent, false);

            mediaTitle = (EditText) row.findViewById(R.id.media_title);
            mediaItem = (ImageView) row.findViewById(R.id.media_item);

            mediaTitle.setText("Add title");
            mediaItem.setImageResource(R.drawable.ic_collection_add);

        }

        return row;
    }
}

fragment_cute_collection.xml

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


    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/gridView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:layout_margin="10dp"
        android:columnWidth="100dp"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:scrollbarStyle="outsideOverlay"
        android:verticalScrollbarPosition="right"
        android:background="@drawable/button_border" />

</RelativeLayout>

grid_row.xml

<?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="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/media_item"
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher" >
    </ImageView>

    <EditText
        android:id="@+id/media_title"
        android:layout_width="105dp"
        android:layout_height="40dp"
        android:textSize="15sp"
        android:gravity="center"
        android:maxLines="1"
        android:maxLength="10"
        android:inputType="text"
        android:imeOptions="actionDone"
        android:layout_gravity="center">
    </EditText>

</LinearLayout>

【问题讨论】:

    标签: android android-layout gridview android-fragments sharedpreferences


    【解决方案1】:

    请在Adapter类中使用加载和保存偏好

    并用偏好值而不是常量值更新 mediaTitle

    mediaTitle.setText("Add title");
    

    偏好代码使用这个

     SharedPreferences mSharedPreferences =getApplicationContext().getSharedPreferences("pref", MODE_PRIVATE);
            /*
             * TO WRITE VALUES INTO THE  PREFERENCE FILE
             */
    
    
            //get Editor object using  sharedPreference edit() Method
    
            Editor mEditor= mSharedPreferences.edit();
            //set boolean Values  into preference files
    
    
            mEditor.putString("stringValue", "hello");
            //set integer value into the preference file
    
            mEditor.commit();
    
    
            /*
             * TO READ THE VALUES FROM THE PREFERENCE FILE
             */
    
            //get the String value from  preference
            String stringValue=mSharedPreferences.getString("stringValue", "default value");
    

    Detail

    【讨论】:

    • 谢谢,但这不起作用。我不能将方法放在一个类中(我认为只有一个活动或片段),因为由于某种原因,inflater 代码没有到达方法中的 EditText,因为我的 mediaTitle 变量上一直有空指针,因为当我尝试打开片段时它崩溃了。我不认为我想将整个代码放在getView() 中(这将使mediaTitle 可访问),因为它只应该第一次设置一个空视图,而不是动态的用户交互。跨度>
    • 另外getApplicationContext() 在片段或类中都不起作用。 getActivity() 适用于片段,getContext() 适用于类。我确实改变了我的常量,只是改为String,但不幸的是没有解决我的问题。
    • 将 getActivity() 作为上下文传递给适配器并使用它们
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多